curl --request POST \
--url https://api.print.app/v2/links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"designId": "design_01J8Z9K2M3N4P5Q6R7S8T9V0W1",
"userData": {
"email": "ada@example.com"
}
}
'import requests
url = "https://api.print.app/v2/links"
payload = {
"designId": "design_01J8Z9K2M3N4P5Q6R7S8T9V0W1",
"userData": { "email": "ada@example.com" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
designId: 'design_01J8Z9K2M3N4P5Q6R7S8T9V0W1',
userData: {email: 'ada@example.com'}
})
};
fetch('https://api.print.app/v2/links', 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.print.app/v2/links",
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([
'designId' => 'design_01J8Z9K2M3N4P5Q6R7S8T9V0W1',
'userData' => [
'email' => 'ada@example.com'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.print.app/v2/links"
payload := strings.NewReader("{\n \"designId\": \"design_01J8Z9K2M3N4P5Q6R7S8T9V0W1\",\n \"userData\": {\n \"email\": \"ada@example.com\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.print.app/v2/links")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"designId\": \"design_01J8Z9K2M3N4P5Q6R7S8T9V0W1\",\n \"userData\": {\n \"email\": \"ada@example.com\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.print.app/v2/links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"designId\": \"design_01J8Z9K2M3N4P5Q6R7S8T9V0W1\",\n \"userData\": {\n \"email\": \"ada@example.com\"\n }\n}"
response = http.request(request)
puts response.read_body{
"object": "link",
"id": "cid_Jx81kQ",
"url": "https://create.print.app/cid_Jx81kQ",
"designId": "design_01J8Z9K2M3N4P5Q6R7S8T9V0W1",
"projectId": null,
"userData": {
"email": "ada@example.com"
},
"expiresAt": "2026-11-26T10:00:00Z",
"created": "2026-10-27T10:00:00Z"
}{
"error": true,
"code": "invalid_request",
"message": "width is required.",
"param": "width",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unauthorized",
"message": "Missing or invalid secret key. Send it as \"Authorization: Bearer sk_…\".",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "account_suspended",
"message": "This account is suspended. Settle the outstanding invoice in the Print.App dashboard.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "not_found",
"message": "Not found.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unsupported_media_type",
"message": "Send the request body as JSON, with \"Content-Type: application/json\".",
"requestId": "FZn-uhymjoEEJow="
}{
"message": "Too Many Requests"
}{
"error": true,
"code": "internal_error",
"message": "Something went wrong on our side. Retry the request; if it keeps failing, contact support with the requestId.",
"requestId": "FZn-uhymjoEEJow="
}Create an editor link
Creates a link that opens a design (for a customer to start from) or a project (to carry on with) in the Print.App editor at create.print.app, without a store.
curl --request POST \
--url https://api.print.app/v2/links \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"designId": "design_01J8Z9K2M3N4P5Q6R7S8T9V0W1",
"userData": {
"email": "ada@example.com"
}
}
'import requests
url = "https://api.print.app/v2/links"
payload = {
"designId": "design_01J8Z9K2M3N4P5Q6R7S8T9V0W1",
"userData": { "email": "ada@example.com" }
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
designId: 'design_01J8Z9K2M3N4P5Q6R7S8T9V0W1',
userData: {email: 'ada@example.com'}
})
};
fetch('https://api.print.app/v2/links', 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.print.app/v2/links",
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([
'designId' => 'design_01J8Z9K2M3N4P5Q6R7S8T9V0W1',
'userData' => [
'email' => 'ada@example.com'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$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.print.app/v2/links"
payload := strings.NewReader("{\n \"designId\": \"design_01J8Z9K2M3N4P5Q6R7S8T9V0W1\",\n \"userData\": {\n \"email\": \"ada@example.com\"\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.print.app/v2/links")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"designId\": \"design_01J8Z9K2M3N4P5Q6R7S8T9V0W1\",\n \"userData\": {\n \"email\": \"ada@example.com\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.print.app/v2/links")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"designId\": \"design_01J8Z9K2M3N4P5Q6R7S8T9V0W1\",\n \"userData\": {\n \"email\": \"ada@example.com\"\n }\n}"
response = http.request(request)
puts response.read_body{
"object": "link",
"id": "cid_Jx81kQ",
"url": "https://create.print.app/cid_Jx81kQ",
"designId": "design_01J8Z9K2M3N4P5Q6R7S8T9V0W1",
"projectId": null,
"userData": {
"email": "ada@example.com"
},
"expiresAt": "2026-11-26T10:00:00Z",
"created": "2026-10-27T10:00:00Z"
}{
"error": true,
"code": "invalid_request",
"message": "width is required.",
"param": "width",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unauthorized",
"message": "Missing or invalid secret key. Send it as \"Authorization: Bearer sk_…\".",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "account_suspended",
"message": "This account is suspended. Settle the outstanding invoice in the Print.App dashboard.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "not_found",
"message": "Not found.",
"requestId": "FZn-uhymjoEEJow="
}{
"error": true,
"code": "unsupported_media_type",
"message": "Send the request body as JSON, with \"Content-Type: application/json\".",
"requestId": "FZn-uhymjoEEJow="
}{
"message": "Too Many Requests"
}{
"error": true,
"code": "internal_error",
"message": "Something went wrong on our side. Retry the request; if it keeps failing, contact support with the requestId.",
"requestId": "FZn-uhymjoEEJow="
}Authorizations
A secret key from Print.App admin → Domains → Secret keys, sent as Authorization: Bearer sk_…. Server-side only.
Headers
Makes a retry safe: a second request with the same key and the same body gets the first response back (for 24 hours) instead of creating the resource again. Use a new key, such as a UUID, for every new request.
1 - 255Body
- LinkCreate
- LinkCreate
What the link opens. Send one of designId or projectId.
A design to start from.
1 - 200A project to carry on with.
1 - 200When the link stops working. Default: 30 days from now. At most a year.
Your own details (customer, order), saved onto projects made through the link.
Response
Created.
An editor link at create.print.app.
"link"Send this to your customer.
The project it opens, or the one a customer saved through it.