Dokumentacja

Publiczne API

Zautomatyzuj swoje Cyfrowe Paszporty Produktów: twórz i aktualizuj produkty, publikuj paszporty, czytaj szablony i importuj katalogi przez proste REST API. Uwierzytelnianie kluczem API.

Wymagany plan

API jest dostępne w każdym planie, także w Free — plany różnią się dziennym limitem, a nie dostępem. Każde żądanie ponownie sprawdza Twoje aktualne uprawnienia.

Adres bazowy

Wszystkie punkty końcowe są dostępne pod prefiksem /v1 w Twojej domenie CyfroPass.

https://<your-domain>/v1

Uwierzytelnianie

Utwórz klucz jako właściciel w Ustawienia → Klucze API. Wyślij go jako token bearer lub w nagłówku X-API-Key. Surowy klucz jest pokazywany tylko raz.

Authorization: Bearer cp_live_…
X-API-Key: cp_live_…

Limity zapytań

Egzekwowanie to dzienny limit (UTC), podzielony na zapisy/dzień (POST/PATCH/PUT/DELETE) i odczyty paszportów/dzień (GET). Free: 100 zapisów + 100 odczytów/dzień; Starter: 1000 zapisów/dzień, odczyty bez limitu; Business i Scale: bez limitu. Po osiągnięciu limitu otrzymasz 429 z komunikatem o dziennym limicie; okno resetuje się o 00:00 UTC. Wysyłaj nagłówek Idempotency-Key przy zapisach, aby bezpiecznie ponawiać — pierwsza odpowiedź jest odtwarzana przez 24 godziny.

Format błędu

Każdy błąd używa jednolitej koperty JSON ze stabilnym, maszynowo czytelnym kodem.

{
  "error": {
    "code": "not_found",
    "message": "not found"
  }
}

Reliability

Request lifecycle & timeouts

Every request passes a layered timeout envelope — a server-level bound plus a finer per-operation timeout on each slow or outbound call — so no connection is ever held open indefinitely.

flowchart TD
  C([Client]) -->|HTTPS / TLS| N[nginx reverse proxy]
  N --> S["HTTP server<br/>ReadHeaderTimeout 10s<br/>ReadTimeout 120s"]
  S --> RL{Auth and rate limit}
  RL -->|"auth 10/min · v1 120/min · leads 5/min"| H[Route handler]
  H --> DB[("PostgreSQL<br/>ping 5s")]
  H --> AI["AI provider<br/>20s"]
  H --> PAY["Stripe / invoice<br/>15s"]
  H --> LK["NIP / VAT registry<br/>10s"]
  H --> CN["Store connector<br/>45s"]
  H --> PDF["PDF render<br/>25s"]
  H --> W["Response<br/>WriteTimeout 120s"]
  W -->|"keep-alive · IdleTimeout 120s"| C
StageTimeout
Request line & headers (slow-loris guard)10 s
Full request read (body — size-capped per route)120 s
Handler execution & response write120 s
Idle keep-alive connection120 s
Database ping5 s
AI provider call20 s
Stripe / invoice fetch15 s
NIP / VAT registry lookup10 s
Store-connector fetch (Shopify / Woo / Presta)45 s
PDF (QR label) render25 s

Referencja

Punkty końcowe

Products

Manage the product catalogue (SKUs) and the documents attached to each product. Fill a template (schema) with data by sending a `data` object keyed by the template's field keys — create with POST, then PATCH merges partial `data` updates. Values are validated against the referenced template version, and the completeness score reflects how many required fields are filled.

GET /products List products (paginated, filterable).
POST /products Create a product from a template version.
GET /products/{id} Fetch one product.
PATCH /products/{id} Update mutable fields; data is merged.
DELETE /products/{id} Delete a draft product. (409 if published)
GET /products/{id}/documents List a product's documents.
POST /products/{id}/documents Upload a document (multipart, ≤ 25 MiB).
GET /products/{id}/documents/{docID} Download a document.
DELETE /products/{id}/documents/{docID} Delete a document.
# Create a product, filling a template (schema) with data
curl -X POST https://app.passflow.example/v1/products \
  -H "Authorization: Bearer cp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "c_garden_furniture_ab12cd34",
    "template_version": "1",
    "name": "Teak bench",
    "data": { "material": "Teak wood", "weatherproof": "yes" }
  }'

Passports

Publish, re-publish and archive passports, and read their immutable version history. Passport routes are keyed by product id.

GET /passports/products/{productID} Current passport (with snapshot).
POST /passports/products/{productID}/publish Publish or re-publish. (422 on validation failure)
POST /passports/products/{productID}/archive Archive the current passport.
GET /passports/products/{productID}/versions Version history (metadata).
GET /passports/products/{productID}/versions/{version} One version's snapshot.
curl -X POST \
  https://app.passflow.example/v1/passports/products/PRODUCT_ID/publish \
  -H "Authorization: Bearer cp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Batches & Serials

Model → batch → serial data inheritance (granularity batch|item). A batch stores a sparse override map (data) over the product; a serial overrides its batch. Effective data layers product ⊕ batch ⊕ serial (child wins). Each batch or serial can be published as its own passport with its own UID/QR. Writes require the owner|editor scope.

GET /products/{id}/batches List a product's batches.
POST /products/{id}/batches Create a batch: {batch_code, data}. data is a sparse override (only the keys you override).
GET /products/{id}/batches/{batchId} Fetch one batch (data, effective_data, inherited_data, completeness).
PATCH /products/{id}/batches/{batchId} Update a batch. data, when present, replaces the override map wholesale (not merged).
DELETE /products/{id}/batches/{batchId} Delete a batch.
GET /products/{id}/batches/{batchId}/serials List a batch's serials.
POST /products/{id}/batches/{batchId}/serials Create a serial: {serial_number, data}. Inherits the batch effective data.
GET /products/{id}/batches/{batchId}/serials/{serialId} Fetch one serial.
PATCH /products/{id}/batches/{batchId}/serials/{serialId} Update a serial. data, when present, replaces its override map wholesale.
DELETE /products/{id}/batches/{batchId}/serials/{serialId} Delete a serial.
POST /products/{id}/batches/{batchId}/publish Publish the batch's own passport (freezes product ⊕ batch data).
DELETE /products/{id}/batches/{batchId}/publish Unpublish the batch passport.
POST /products/{id}/serials/{serialId}/publish Publish the serial passport (serial addressed by id alone; its batch is resolved server-side).
DELETE /products/{id}/serials/{serialId}/publish Unpublish the serial passport.
curl -X POST \
  https://app.passflow.example/v1/products/PRODUCT_ID/batches \
  -H "Authorization: Bearer cp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"batch_code":"LOT-2026-04","data":{"composition":"100% recycled cotton"}}'

Templates (schemas)

Read the platform-provided, versioned product-group templates — or build your OWN custom templates (schemas): a set of sections, each holding typed fields (key, type, label, required, access, plus per-type options). Custom templates are private to your account and become selectable when creating products. The available field types come from /templates/field-types. Send the schema document to POST /templates/custom — the id is generated server-side (c_<slug>_<hex>) and every custom template starts at version "1"; edit it in place while it is a draft.

GET /templates List templates and their versions (platform + your custom ones).
GET /templates/field-types The generic field-type registry (allowed field types).
GET /templates/{id} List versions of one template.
GET /templates/{id}/{version} Full template document (sections, fields).
POST /templates/{id}/{version}/validate Validate product data against a version.
GET /templates/{id}/diff Diff two versions (from, to).
GET /templates/custom List your account's custom templates (schemas).
POST /templates/custom Create a custom template (schema): {label, granularity, sections:[{label, fields:[...]}]}. Returns the stored template with its generated id. (422 invalid_template · 409 template_limit)
PUT /templates/custom/{id} Update a draft custom template (owner only). (409 template_not_draft)
DELETE /templates/custom/{id} Delete a custom template. (409 template_in_use if products reference it)
# Create a new schema (custom template)
curl -X POST https://app.passflow.example/v1/templates/custom \
  -H "Authorization: Bearer cp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "label": "Garden furniture",
    "granularity": "model",
    "sections": [
      { "label": "Basics", "fields": [
        { "key": "material", "type": "text", "label": "Material", "required": true, "access": "public" },
        { "key": "weatherproof", "type": "enum", "label": "Weatherproof", "options": ["yes","no"], "access": "public" }
      ]}
    ]
  }'

Import

Bulk-import products from a CSV file or a connected Shopify / WooCommerce / PrestaShop store. Every fetch becomes an import job with the same map → validate → execute lifecycle.

POST /import/upload Upload a CSV (multipart, ≤ 10 MB).
POST /import/sources/test Test a store connector.
POST /import/sources/fetch Fetch a store catalogue into a job.
POST /import/{job}/mapping-suggest Suggest a column → field mapping.
POST /import/{job}/validate Validate mapped rows (no products created).
POST /import/{job}/execute Create products from valid rows. (idempotent)
GET /import/{job} Get import job status.
curl -X POST https://app.passflow.example/v1/import/upload \
  -H "Authorization: Bearer cp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -F "file=@products.csv"

Pełna, maszynowo czytelna specyfikacja jest dostępna jako openapi.yaml.