Uploads
Create an upload
Declares a file and returns a short-lived presigned target to send its
bytes to. Requires customisers:write and an Idempotency-Key.
Overview
The purpose selects the accepted file types and the size cap, so
declare the purpose of the slot you intend to attach to. Both the
filename extension and the content type must be ones the purpose accepts;
a mismatch answers 422 with the accepted values, and an oversized
declaration answers 422 with max_byte_size.
Send the bytes with the upload_target: use its method, its url, and
every header it lists, with the file as the raw request body. The target
expires about ten minutes after it is issued and is returned only by this
response, so do not cache or store it. An idempotent replay of this
request returns the recorded body with upload_target set to null, which
means a retry after the target expired needs a new upload rather than the
same one. Poll GET/api/v3/uploads/{upload_id} to confirm the bytes
landed.
Nothing is verified here. The declared size and type are what the API
will issue a target for; the actual bytes are checked when you attach the
upload to a file slot, and a file that fails that check is refused then.
Authorisation
Bearer token required. Include it in theAuthorization header.
Required scope: customisers:write
Request body
Request body example
{
"purpose": "font_ttf",
"filename": "Signature.ttf",
"content_type": "font/ttf",
"byte_size": 184320
}curl https://web.signcustomiser.com/api/v3/uploads \
--request POST \
--header 'Accept: application/json' \
--header 'Authorization: Bearer YOUR_API_TOKEN' \
--header 'Content-Type: application/json' \
--data '{
"purpose": "font_ttf",
"filename": "Signature.ttf",
"content_type": "font/ttf",
"byte_size": 184320
}'{
"data": {
"object": "upload",
"id": "upl_9f2c4b7ad13e6058ba41cd",
"purpose": "font_ttf",
"filename": "Signature.ttf",
"content_type": "font/ttf",
"byte_size": 184320,
"status": "pending",
"verification_failure_code": null,
"expires_at": "2026-07-23T00:00:00Z",
"attached_at": null,
"created_at": "2026-07-22T00:00:00Z",
"upload_target": {
"method": "PUT",
"url": "https://uploads.example.invalid/staged-upload-target-example",
"headers": {},
"expires_at": "2026-07-22T00:10:00Z"
}
},
"links": {
"self": "https://web.signcustomiser.com/api/v3/uploads/upl_9f2c4b7ad13e6058ba41cd",
"documentation": "https://www.signcustomiser.com/help/api/"
},
"meta": {
"api_version": "v3",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}
}{
"type": "https://www.signcustomiser.com/help/api/problems/missing_idempotency_key",
"title": "Missing idempotency key",
"status": 400,
"code": "missing_idempotency_key",
"detail": "Provide an Idempotency-Key header for this write.",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}{
"type": "https://www.signcustomiser.com/help/api/problems/missing_api_key",
"title": "Missing API key",
"status": 401,
"code": "missing_api_key",
"detail": "Provide a store API key as a bearer token.",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}{
"type": "https://www.signcustomiser.com/help/api/problems/insufficient_scope",
"title": "Insufficient scope",
"status": 403,
"code": "insufficient_scope",
"detail": "This operation requires the customisers:write scope.",
"required_scopes": [
"customisers:write"
],
"granted_scopes": [
"customisers:read"
],
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}{
"type": "https://www.signcustomiser.com/help/api/problems/idempotency_key_conflict",
"title": "Idempotency key conflict",
"status": 409,
"code": "idempotency_key_conflict",
"detail": "This Idempotency-Key was already used for a different request body on this operation.",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}{
"type": "https://www.signcustomiser.com/help/api/problems/upload_type_not_allowed",
"title": "Upload type not allowed",
"status": 422,
"code": "upload_type_not_allowed",
"detail": "The font_ttf purpose does not accept application/pdf files.",
"errors": [
{
"pointer": "/content_type",
"code": "unsupported_value",
"detail": "The font_ttf purpose does not accept application/pdf files.",
"allowed_values": [
"font/ttf"
]
}
],
"purpose": "font_ttf",
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}{
"type": "https://www.signcustomiser.com/help/api/problems/rate_limited",
"title": "Too many requests",
"status": 429,
"code": "rate_limited",
"detail": "You have exceeded the request limit for this API key.",
"retry_after": 60,
"request_id": "req_01jz9x2k7c8f3m5n6p7q8r9s0t"
}