Corporate gifting · API v1

Your gifting program, connected.

Bring your employee calendar, client relationships and procurement workflow into Printonic. Start with a test key, quote a gift, then follow it through delivery.

Start in three steps

  1. Sign in as the team owner. Open Integrations → API keys, acknowledge access, enable the API and create a test key.
  2. Choose a role and scopes. Use an approver service account for roster, rules and finance access. Save the key when it appears; it is shown once.
  3. Read GET /team, browse GET /collections, then quote and create a team order. Keep the returned ID and reuse your idempotency key for retries.
export PRINTONIC_TEAMS_API_KEY='ptk_test_…'
export PRINTONIC_API_BASE='https://staging.printonic.com/api/teams/v1'

curl --fail-with-body "$PRINTONIC_API_BASE/team" \
  -H "Authorization: Bearer $PRINTONIC_TEAMS_API_KEY"

curl --fail-with-body "$PRINTONIC_API_BASE/team-orders" \
  -H "Authorization: Bearer $PRINTONIC_TEAMS_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: welcome-alex-2026-10-01' \
  --data '{"collection":"welcome","headcount":1,"gift_message":"Welcome aboard!"}'

Use https://staging.printonic.com/api/teams/v1 while testing this release. The production base after promotion is https://platform.printonic.com/api/teams/v1. Download the OpenAPI specification.

One key, one team

Keys begin with ptk_live_ or ptk_test_. Send them in Authorization: Bearer or X-API-Key. Each service account has a requester or approver role and explicit scopes. Roles never grant owner rights or permission to sign approvals. Key creation and revocation require the owner’s signed-in session.

ScopeAccess
catalog:readRead gifts and catalog
people:readRead the employee roster
people:writeUpdate the employee roster
contacts:readSearch connected CRM contacts
gifts:sendPrepare gift sends
orders:readRead team orders and approval requests
orders:writePrepare and update team orders
orders:payPay within owner-approved limits
artwork:writeManage gift artwork and previews
rules:writeManage gifting rules
billing:readRead billing and finance documents
billing:writeManage billing configuration and funding requests
webhooks:manageManage webhook subscriptions

The team API switch and the account Agent Access suspension both disable keys. Revocation takes effect on the next authenticated request. Requests have plan-based per-key limits and appear in usage history and the activity feed.

Payments and approvals

Orders and gift sends are held for human approval by default. An owner may grant a live REST key orders:pay with a per-request spending ceiling and a monthly ceiling. A batch must fit within the per-request ceiling as a whole. Reserved and uncertain payments count toward the monthly cap in America/Los_Angeles time. Current prices, proofs, balance and credit terms are checked again before payment.

For a bounded net-terms purchase, pass payment_method: "net_terms" when creating an order, or call POST /funding with {"method":"net_terms","campaign_id":123} for an unpaid order created by the same key. This requires billing:write and orders:pay. Bank funding uses bank_transfer (deposit invoice) or us_bank_account (an ACH intent when enabled). Creating an intent does not confirm a bank payment.

Assistants never approve, fund or pay. MCP tools hold orders even when the credential has a pay scope. Proof signing requires a signed-in approver and the current proof version. API-created rules hold their sends. Large-campaign processing prepares shipments; a human approves payment in Printonic.

Reliable requests and private responses

Use a stable Idempotency-Key of 1–128 printable characters on each endpoint marked below. Reusing it with the same request replays the result; changing the payload returns 409. After an uncertain write, read the resource before trying a new key. Do not generate a fresh key for each network retry.

Lists use limit and an opaque cursor. Follow next_cursor until it is null. Cursors belong to their team, collection and filters. Rate responses include X-RateLimit-*; on 429, honor Retry-After. Every response includes X-Request-Id.

{"error":{"code":"insufficient_scope","message":"This key does not have the required Teams scope.","request_id":"…"}}

Responses and exports omit recipient emails, claim URLs and tokens, including nested provider errors. An integration can supply a work email to update a roster or send a gift, then follow the returned IDs. Request bodies cannot choose a different team or owner.

Endpoint reference

All paths are relative to /api/teams/v1. GET/POST /keys and DELETE /keys/{id} require an owner session. POST /proofs/{id}/sign requires an approver session. Every other endpoint uses the key’s listed scopes.

Method and pathScopesIdempotency key
GET /teamActive keyOptional
GET /memberspeople:readOptional
GET /collectionscatalog:readOptional
GET /collections/:slugcatalog:readOptional
GET /itemscatalog:readOptional
GET /items/:slug/optionscatalog:readOptional
GET /people/upcomingpeople:readOptional
GET /peoplepeople:readOptional
POST /peoplepeople:writeOptional
PATCH /people/:idpeople:writeOptional
DELETE /people/:idpeople:writeOptional
GET /contactscontacts:readOptional
POST /giftsgifts:sendRequired
GET /giftsorders:readOptional
GET /gifts/:id/timelineorders:readOptional
GET /gifts/:idorders:readOptional
POST /team-orders/quotecatalog:readOptional
POST /team-ordersorders:writeRequired
GET /team-ordersorders:readOptional
GET /team-orders/:id/manifest.csvorders:readOptional
GET /team-orders/:id/proofsorders:readOptional
GET /team-orders/:idorders:readOptional
POST /team-orders/:id/cancelorders:writeRequired
PATCH /team-orders/:idorders:writeOptional
POST /team-orders/:id/request-approvalorders:writeRequired
GET /approvalsorders:readOptional
GET /approvals/:idorders:readOptional
GET /billing/balancebilling:readOptional
GET /invoicesbilling:readOptional
GET /invoices/:id.pdfbilling:readOptional
GET /receipts/:id.pdfbilling:readOptional
GET /statements/:monthbilling:readOptional
GET /cost-centersbilling:readOptional
GET /credit-termsbilling:readOptional
POST /webhookswebhooks:manageOptional
GET /webhookswebhooks:manageOptional
DELETE /webhooks/:idwebhooks:manageOptional
POST /webhooks/:id/testwebhooks:manageRequired
GET /artworkartwork:writeOptional
POST /artworkartwork:writeRequired
POST /artwork/previewsartwork:writeRequired
GET /previews/:idartwork:writeOptional
GET /print-areascatalog:readOptional
GET /templatesorders:readOptional
POST /templatesorders:writeRequired
GET /templates/:id/useorders:readOptional
GET /templates/:idorders:readOptional
PUT /templates/:idorders:writeOptional
DELETE /templates/:idorders:writeOptional
GET /rulesrules:writeOptional
POST /rulesrules:writeRequired
POST /rules/evaluaterules:writeRequired
GET /rules/:id/previewrules:writeOptional
GET /rules/:idrules:writeOptional
PATCH /rules/:idrules:writeOptional
DELETE /rules/:idrules:writeOptional
POST /proofs/:id/versionsartwork:writeRequired
POST /proofs/:id/reviewartwork:writeRequired
POST /proofs/:id/signApprover sessionRequired
POST /large-campaignsorders:writeRequired
GET /large-campaigns/:idorders:readOptional
PATCH /large-campaigns/:idorders:writeRequired
POST /large-campaigns/:id/processorders:writeRequired
GET /storecatalog:readOptional
POST /store/quotecatalog:readOptional
POST /store/ordersorders:writeRequired
POST /fundingbilling:writeRequired
POST /deposit-invoicesbilling:writeRequired
POST /tax-certificatesbilling:writeRequired
POST /cost-centersbilling:writeOptional
PUT /billing/profilebilling:writeOptional
GET /recipient-brandingorders:readOptional
PATCH /recipient-brandingorders:writeOptional
POST /sandbox/eventsorders:writeRequired

HR, CRM and programs

POST /people accepts a people array with work_email, first_name, last_name, start_date, birthday (MM-DD), department, location, country, zip and status. Upserts match the work email. Provider-managed fields stay controlled by that provider. Roster and upcoming-date reads require an approver key with people:read.

POST /gifts accepts 1–50 recipients: {person_id:123}, {crm:{provider:"hubspot",id:"1842",object_type:"contact"}}, or a typed name and email. Choose one of gift.collection_slug, gift.item_slug or gift.items. Connected CRM IDs are resolved server-side within the team.

const base = process.env.PRINTONIC_API_BASE;
const response = await fetch(base + '/gifts', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer ' + process.env.PRINTONIC_TEAMS_API_KEY,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'crm-deal-1842-thank-you-v1'
  },
  body: JSON.stringify({
    recipients: [{ crm: { provider: 'hubspot', id: '1842', object_type: 'contact' } }],
    gift: { collection_slug: 'thank-you' },
    message: 'Thank you for choosing us.'
  })
});
const result = await response.json();
if (!response.ok) throw new Error(result.error.code + ': ' + result.error.message);
console.log(result); // IDs and status; no recipient email or claim link

Use kind=hr or kind=crm for rules. Template use returns a fresh campaign_input with its template revision; add new recipients and submit it to team-orders. Gift-choice menus use gift_choices with bundle mode. Large campaigns accept up to 5,000 recipients. The process endpoint prepares the next batch; action: "stop" stops the program. Use pause and resume to control preparation. Reprice processes one unpaid batch per request; repeat with a fresh Idempotency-Key until the program returns to awaiting_approval. These actions clear prior payment authority, and changed prices require renewed human approval. Paid batches keep their existing totals.

Artwork, proofs and procurement

Upload artwork from a public HTTPS image URL, then submit placements to POST /artwork/previews. Poll GET /previews/{id} for the actual renderer result. Read print areas before placing art. Proof version and review calls operate on the order item ID; the team-order proofs read uses the campaign ID.

Finance reads include balance, credit terms, invoices, receipts, monthly statements and cost centers. Download PDF documents at the listed paths, or add ?format=pdf to a statement. Billing writes require an approver key with billing:write. Tax certificates use a public HTTPS PDF, PNG, JPEG or WebP URL, up to 10 MB.

import json, os, urllib.request, urllib.error

base = os.environ['PRINTONIC_API_BASE']
headers = {'Authorization': 'Bearer ' + os.environ['PRINTONIC_TEAMS_API_KEY']}
cursor = None
while True:
    url = base + '/people?limit=100' + ('&cursor=' + cursor if cursor else '')
    with urllib.request.urlopen(urllib.request.Request(url, headers=headers)) as r:
        page = json.load(r)
    for person in page['data']:
        print(person['id'], person.get('display_name'))
    cursor = page['next_cursor']
    if not cursor:
        break

Sandbox and webhooks

A test key gets an isolated resource namespace within its team. Test records have UUID IDs. Quotes use live catalog prices; selecting a collection may prepare reusable catalog draft products. Test orders never enter production, send recipient emails or move money. Simulated records and webhooks carry livemode: false.

Use POST /sandbox/events with {"type":"team_order.shipped","resource_id":"RETURNED_TEST_ORDER_UUID"} and an Idempotency-Key to advance a simulated order and exercise webhook delivery. Test artwork and proofs model metadata and review states without rendering images. Test CRM automation uses sandbox roster or typed recipients; it does not read connected providers. Live keys use the existing real renderers and CRM integrations.

Create a test subscription with POST /webhooks. Save its signing secret from the creation response. Verify X-Printonic-Signature: the timestamp and raw body are signed as HMAC-SHA256(secret, timestamp + "." + rawBody). Use constant-time comparison, reject stale timestamps and deduplicate event IDs. Delivery retries use the existing webhook queue and eventually dead-letter repeated failures.

Events cover sent/claimed/shipped/delivered gifts, team-order fulfillment, requested/decided approvals, issued/paid invoices and low balances. A balance.low subscription requires balance_threshold_cents and fires on a real downward crossing. Test subscriptions receive events from the same test key only; live subscriptions belong to the team.

Connect assistants and Zapier

Use the same Teams key at the hosted MCP endpoint. The Teams assistant reference describes all available tools. OAuth follows the existing environment’s sign-in configuration.

The repository includes a Zapier integration for gift sends, roster upserts and signed lifecycle events, using these same API calls. It must be registered and published in the Printonic Zapier developer account before it appears in the Zapier directory.