printsked.com

Docs API

PrintSked API Reference
PRINTSKED ยท API REFERENCE

Read and write your shop's jobs, customers, quotes, and invoices.

A REST API for building integrations โ€” Zapier workflows, custom automations, or anything else your shop needs to connect to PrintSked.

Authentication

Every request needs an API key, sent as a bearer token.

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Create a key from inside PrintSked under Settings โ†’ Integrations โ†’ API Keys. Each key can be scoped to specific resources and set to read-only or read + write โ€” write access (creating or updating records) requires a key with write permission.

Keep it safe: the raw key is shown once, at creation. PrintSked stores only a hash of it and can't recover a lost key โ€” create a new one if it's misplaced.

Base URL

https://hfypdyhmafppzjktlvoz.supabase.co/functions/v1/api-v1

This URL is the same for every shop โ€” your API key is what identifies your account, not the URL.

Resources

Every record is otherwise a free-form set of fields โ€” send any additional fields your workflow needs (notes, custom identifiers, etc.) and they'll be stored on the record.

jobs

Print jobs in production. Required on create: customer, product

customers

Customer records. Required on create: name

quotes

Quotes sent to customers. No fields are required on create.

invoices

Invoices billed to customers. Required on create: customer

Reading records

Lists records for a resource, newest first by default, or fetch a single record by id.

GET/{resource}
ParamDescription
limitMax results per page. Default 25, max 100.
offsetPagination offset. Default 0.
since / untilISO date range filter on createdAt.
sortcreated_at (default) or updated_at.
orderasc or desc (default).
Resource-specific filterse.g. ?status=unpaid on invoices, ?customer=Acme on jobs โ€” see the field reference for which fields are filterable per resource.
curl "https://hfypdyhmafppzjktlvoz.supabase.co/functions/v1/api-v1/customers?limit=5" \
  -H "Authorization: Bearer sk_live_..."
{
  "data": [
    {
      "id": "a4068ff5-32f4-4819-a22e-a5f8557ac822",
      "name": "Sameer",
      "email": "sameer@example.com",
      "phone": "5544554455",
      "company": "SC",
      "tier": "wholesale",
      "createdAt": "2026-08-01T17:40:42.876043+00:00",
      "updatedAt": "2026-08-01T17:44:17.481665+00:00"
    }
  ],
  "pagination": { "limit": 5, "offset": 0, "total": 42 }
}
GET/{resource}/{id}

Fetches a single record by id.

curl "https://hfypdyhmafppzjktlvoz.supabase.co/functions/v1/api-v1/customers/a4068ff5-32f4-4819-a22e-a5f8557ac822" \
  -H "Authorization: Bearer sk_live_..."

Creating records

POST/{resource}

Creates a new record. Requires a key with write permission. Send the required fields for that resource plus any extra fields you want stored.

curl -X POST "https://hfypdyhmafppzjktlvoz.supabase.co/functions/v1/api-v1/jobs" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"customer":"Acme Co","product":"Vinyl Banner"}'
{
  "id": "c2d337ef-720a-4723-9c4f-75549ae2a3f6",
  "customer": "Acme Co",
  "product": "Vinyl Banner",
  "createdAt": "2026-09-03T18:57:36.318214+00:00",
  "updatedAt": "2026-09-03T18:57:36.318214+00:00"
}

Responses are 201 Created on success. A 413 is returned if the request body exceeds 256KB.

Updating records

PATCH/{resource}/{id}

Updates an existing record. Requires a key with write permission. Send only the fields you want to change.

curl -X PATCH "https://hfypdyhmafppzjktlvoz.supabase.co/functions/v1/api-v1/jobs/c2d337ef-720a-4723-9c4f-75549ae2a3f6" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"product":"18oz Vinyl Banner"}'
There is no delete endpoint โ€” records can be edited but not permanently removed through the API.

Field reference

A few fields on each resource are protected: some never leave the API in either direction, and some are visible on GET but can't be set via POST/PATCH because PrintSked only ever changes them through its own guarded logic (payment recording, margin calculations, etc.).

ResourceNever exposedRead-only (visible, not settable)
jobsinternalNoteslaborCost, materialCost, customerId
customersinternalNotestier, creditLimit, currentBalance, depositRequired, paymentTerms, totalLifetimeValue, totalJobs
quotesinternalNotestotal
invoicesโ€”amount, balance, status, paymentHistory

Rate limits

Requests are limited to 120 per minute per API key, and 300 per minute in total across every key your shop has issued. Every response includes headers showing where you stand:

X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Shop-Limit: 300
X-RateLimit-Shop-Remaining: 284

Exceeding a limit returns 429 Too Many Requests with a Retry-After header.

Idempotency

To safely retry a POST without risking a duplicate record, send an Idempotency-Key header with a unique value. Retrying with the same key returns the original response instead of creating a second record.

curl -X POST ".../api-v1/customers" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Idempotency-Key: my-unique-request-id-123" \
  -H "Content-Type: application/json" \
  -d '{"name":"Acme Co"}'

Errors

StatusMeaning
400Invalid request โ€” missing a required field, bad query parameter, etc.
401Missing, invalid, revoked, or expired API key.
403The key doesn't have access to this resource, or is read-only and you attempted a write.
404Unknown resource or record id.
413Request body larger than 256KB.
429Rate limit exceeded โ€” see Rate limits.

Error responses are JSON with a human-readable message:

{ "error": "This API key does not have access to \"invoices\"" }
Scroll to Top