curl --request POST \
--url https://api.adspo.co/v1/creatives/{creative_id}/save \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"workspace_id": "0133afa6-5326-4a70-aa10-c9358eb6de04"
}
'import requests
url = "https://api.adspo.co/v1/creatives/{creative_id}/save"
payload = { "workspace_id": "0133afa6-5326-4a70-aa10-c9358eb6de04" }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({workspace_id: '0133afa6-5326-4a70-aa10-c9358eb6de04'})
};
fetch('https://api.adspo.co/v1/creatives/{creative_id}/save', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.adspo.co/v1/creatives/{creative_id}/save",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'workspace_id' => '0133afa6-5326-4a70-aa10-c9358eb6de04'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.adspo.co/v1/creatives/{creative_id}/save"
payload := strings.NewReader("{\n \"workspace_id\": \"0133afa6-5326-4a70-aa10-c9358eb6de04\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.adspo.co/v1/creatives/{creative_id}/save")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"workspace_id\": \"0133afa6-5326-4a70-aa10-c9358eb6de04\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.adspo.co/v1/creatives/{creative_id}/save")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"workspace_id\": \"0133afa6-5326-4a70-aa10-c9358eb6de04\"\n}"
response = http.request(request)
puts response.read_body{
"creative_id": "<string>",
"workspace_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"board_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"saved_at": "2023-11-07T05:31:56Z",
"already_saved": true,
"already_on_board": true
}{
"creative_id": "f930d886d0fb9e86b9dd6c1200dab7ef",
"workspace_id": "0133afa6-5326-4a70-aa10-c9358eb6de04",
"board_id": null,
"saved_at": "2026-11-02T14:05:11Z",
"already_saved": false
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "Save limit reached: at most 30 saves per minute."
}{
"error": "<string>"
}Save creative
Saves a creative to your library, like the save button in the app: into workspace_id, or your default workspace if that’s left out. To put it on a board, use Add creative to board.
The save is yours: the key’s owner, or through the MCP, the person who connected it.
A new save returns 201 and costs 1 credit. Saving something already saved in that workspace changes nothing, returns 200 with already_saved: true, and is free, as are requests that fail. Saves are limited to 30 a minute per person, on top of the usual limits.
curl --request POST \
--url https://api.adspo.co/v1/creatives/{creative_id}/save \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"workspace_id": "0133afa6-5326-4a70-aa10-c9358eb6de04"
}
'import requests
url = "https://api.adspo.co/v1/creatives/{creative_id}/save"
payload = { "workspace_id": "0133afa6-5326-4a70-aa10-c9358eb6de04" }
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({workspace_id: '0133afa6-5326-4a70-aa10-c9358eb6de04'})
};
fetch('https://api.adspo.co/v1/creatives/{creative_id}/save', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.adspo.co/v1/creatives/{creative_id}/save",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'workspace_id' => '0133afa6-5326-4a70-aa10-c9358eb6de04'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.adspo.co/v1/creatives/{creative_id}/save"
payload := strings.NewReader("{\n \"workspace_id\": \"0133afa6-5326-4a70-aa10-c9358eb6de04\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.adspo.co/v1/creatives/{creative_id}/save")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"workspace_id\": \"0133afa6-5326-4a70-aa10-c9358eb6de04\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.adspo.co/v1/creatives/{creative_id}/save")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"workspace_id\": \"0133afa6-5326-4a70-aa10-c9358eb6de04\"\n}"
response = http.request(request)
puts response.read_body{
"creative_id": "<string>",
"workspace_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"board_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"saved_at": "2023-11-07T05:31:56Z",
"already_saved": true,
"already_on_board": true
}{
"creative_id": "f930d886d0fb9e86b9dd6c1200dab7ef",
"workspace_id": "0133afa6-5326-4a70-aa10-c9358eb6de04",
"board_id": null,
"saved_at": "2026-11-02T14:05:11Z",
"already_saved": false
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "<string>"
}{
"error": "Save limit reached: at most 30 saves per minute."
}{
"error": "<string>"
}Authorizations
Your Adspo API key.
Path Parameters
The creative ID.
Body
The workspace to save it in (from Get workspaces), or default. Defaults to the default workspace.
Response
Already saved in that workspace. Nothing changed, and no credit was used.
The workspace it's saved in. null for the default workspace.
The board it was added to. null for a save without a board.
When it was saved. For something already saved, when that was.
Whether it was already saved in that workspace.
Whether it was already on the board. Only present when adding to a board.