Документация API

Интегрируйте создание пассов в ваши приложения

Только для тарифа Pro. REST API доступен только на тарифе Pro. На тарифах Free и Basic создание API-ключей недоступно. Посмотреть тарифы →

Contents

Аутентификация

All API requests require a valid API key sent in the Authorization header. API keys can be created in the Dashboard → API section (Pro plan, admin only).

Authorization: Bearer 2pk_your_api_key_here

Базовый URL

https://your-domain.com/api/v1

All endpoints below are relative to this base URL. CORS is enabled — preflight OPTIONS is supported on every endpoint.

Лимиты запросов

  • 30 requests per minute per API key for /passes, /clients, /scan
  • 10 requests per minute per API key for /webhooks and /triggers
  • Rate limit headers in responses: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • When rate limited, a 429 response includes a Retry-After header

Коды ошибок

CodeDescription
400Bad Request — invalid input or JSON body
401Unauthorized — missing or invalid API key
403Forbidden — plan limit reached, not on Pro plan, or webhook quota exceeded
404Not Found — resource does not exist or belongs to another tenant
429Too Many Requests — rate limit exceeded
500Internal Server Error

All errors return JSON: { "error": "message" }

Эндпоинты

GET/passesСписок пассов

Параметры запроса

FieldTypeDescription
searchstringMatch by pass name or code
statusstringactive, used, expired, revoked
limitnumberPage size (default 25, max 100)
pagenumberPage number (default 1)

Ответ (200)

[
  {
    "id": "clx1abc...",
    "code": "AbCd1234EfGh",
    "name": "VIP Guest",
    "type": "single",
    "status": "active",
    "usagesCount": 0,
    "maxUsages": null,
    "validFrom": null,
    "validUntil": "2025-12-31T23:59:59.000Z",
    "client": { "name": "John Doe", "email": "john@example.com" },
    "publicUrl": "https://your-domain.com/p/AbCd1234EfGh?token=...",
    "createdAt": "2025-06-01T12:00:00.000Z"
  }
]

POST/passesСоздание пасса

Тело запроса

FieldTypeRequiredDescription
typestringYes"single" or "multi"
namestringNoHuman-readable label
notestringNoInternal note (not shown on public page)
clientNamestringNoAuto-create or attach client by name
maxUsagesnumberNoMax scan count for multi passes (null = unlimited)
validFromstringNoISO 8601 date (e.g. "2025-06-01T00:00:00Z")
validUntilstringNoISO 8601 date
customFieldsarrayNoArray of { "key": "...", "value": "...", "isPublic": true }
templateIdstringNoPass template ID for styling
locationIdstringNoLocation ID to attach

Ответ (201)

{
  "id": "clx1abc...",
  "code": "AbCd1234EfGh",
  "name": "VIP Guest",
  "type": "single",
  "status": "active",
  "maxUsages": null,
  "usagesCount": 0,
  "validFrom": null,
  "validUntil": "2025-12-31T23:59:59.000Z",
  "publicUrl": "https://your-domain.com/p/AbCd1234EfGh?token=...",
  "createdAt": "2025-06-01T12:00:00.000Z"
}

GET/passes/:passIdПолучить пасс

Returns the full pass including custom fields and attached client.

Ответ (200)

{
  "id": "clx1abc...",
  "code": "AbCd1234EfGh",
  "name": "VIP Guest",
  "type": "single",
  "status": "active",
  "usagesCount": 0,
  "maxUsages": null,
  "validFrom": null,
  "validUntil": "2025-12-31T23:59:59.000Z",
  "fields": [
    { "key": "Full Name", "value": "John Doe", "isPublic": true }
  ],
  "client": {
    "id": "clx2...", "name": "John Doe", "email": "john@example.com", "phone": null
  },
  "publicUrl": "https://your-domain.com/p/AbCd1234EfGh?token=...",
  "createdAt": "2025-06-01T12:00:00.000Z",
  "updatedAt": "2025-06-01T12:00:00.000Z"
}

PATCH/passes/:passIdОбновить пасс

Тело запроса

FieldTypeRequiredDescription
namestringNoUpdate label
notestringNoInternal note
statusstringNo"active" or "revoked"
maxUsagesnumber | nullNoUpdate scan limit
validFromstring | nullNoISO 8601 date or null
validUntilstring | nullNoISO 8601 date or null
customFieldsarrayNoReplaces all existing fields

When customFields is provided, all existing fields are replaced. Status change emits a pass.status_changed webhook.

POST/passes/:passId/activateАктивировать пасс

Sets status to active. Returns 400 if already active. Emits pass.status_changed and notifies wallet apps.

Ответ (200)

{ "id": "clx1abc...", "code": "AbCd1234EfGh", "name": "VIP Guest", "status": "active" }

POST/passes/:passId/revokeОтозвать пасс

Sets status to revoked. Returns 400 if already revoked. Emits pass.status_changed and notifies wallet apps.

Ответ (200)

{ "id": "clx1abc...", "code": "AbCd1234EfGh", "name": "VIP Guest", "status": "revoked" }

POST/scanСканировать пасс

Тело запроса

FieldTypeRequiredDescription
codestringYesThe pass code (from QR or public URL)

Validates the pass against status, validity dates, and usage limits. Records a scan and emits pass.scanned.single passes flip to used after the first successful scan.

Ответ (200)

{
  "success": true,
  "result": "success",
  "pass": {
    "id": "clx1abc...",
    "code": "AbCd1234EfGh",
    "name": "VIP Guest",
    "type": "single",
    "status": "used",
    "usagesCount": 1,
    "maxUsages": null
  },
  "scan": { "id": "clx3...", "scannedAt": "2025-06-01T12:30:00.000Z" }
}

On failure, response is 200 with success: false and result:revoked, already_used, not_yet_valid, expired, max_usages_reached.

GET/clientsСписок клиентов

Параметры запроса

FieldTypeDescription
searchstringMatch by name, email or phone
limitnumberPage size (default 25, max 100)
pagenumberPage number (default 1)

Ответ (200)

[
  {
    "id": "clx2...",
    "name": "John Doe",
    "email": "john@example.com",
    "phone": "+1234567890",
    "notes": null,
    "createdAt": "2025-06-01T12:00:00.000Z"
  }
]

POST/clientsСоздать клиента

Тело запроса

FieldTypeRequiredDescription
namestringYesClient display name
emailstringNoEmail address
phonestringNoPhone number
notesstringNoInternal notes

Ответ (201)

{
  "id": "clx2...",
  "name": "John Doe",
  "email": "john@example.com",
  "phone": null,
  "notes": null,
  "createdAt": "2025-06-01T12:00:00.000Z"
}

Emits client.created webhook.

GET/clients/:clientIdПолучить клиента

Ответ (200)

{
  "id": "clx2...",
  "name": "John Doe",
  "email": "john@example.com",
  "phone": "+1234567890",
  "notes": "VIP customer",
  "createdAt": "2025-06-01T12:00:00.000Z"
}

GET/webhooksСписок вебхуков

Ответ (200)

[
  {
    "id": "wh_...",
    "event": "pass.scanned",
    "targetUrl": "https://example.com/hook",
    "active": true,
    "createdAt": "2025-06-01T12:00:00.000Z"
  }
]

POST/webhooksПодписаться на вебхук

Тело запроса

FieldTypeRequiredDescription
eventstringYesOne of: pass.created, pass.scanned, pass.status_changed, client.created
targetUrlstringYesHTTPS URL receiving POST payloads

Tenant has a fixed webhook quota — exceeding it returns 403. Subscribed events POST a JSON payload to targetUrl.

Ответ (201)

{
  "id": "wh_...",
  "event": "pass.scanned",
  "targetUrl": "https://example.com/hook",
  "active": true,
  "createdAt": "2025-06-01T12:00:00.000Z"
}

DELETE/webhooks/:webhookIdОтписаться от вебхука

Ответ (200)

{ "success": true }

GET/triggersОпрос триггеров

Polling fallback used by Zapier. Returns recent items for the requested event since a given timestamp.

Параметры запроса

FieldTypeRequiredDescription
eventstringYesOne of: pass.created, pass.scanned, pass.status_changed, client.created
sincestringNoISO 8601 date — return items after this time (default last 24h)
limitnumberNoMax items (default 50, max 100)

Each event returns a different shape — for pass.created the items match the list-passes response with extra fields, clientName, clientEmail, clientPhone; for pass.scanned each item is a flat scan record; for pass.status_changed a pass with changedAt; for client.created the client record.

Примеры

curl — create pass

curl -X POST https://your-domain.com/api/v1/passes \
  -H "Authorization: Bearer 2pk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "single",
    "name": "VIP Guest",
    "validUntil": "2025-12-31T23:59:59Z",
    "customFields": [
      { "key": "Full Name", "value": "John Doe", "isPublic": true }
    ]
  }'

curl — scan pass

curl -X POST https://your-domain.com/api/v1/scan \
  -H "Authorization: Bearer 2pk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "code": "AbCd1234EfGh" }'

curl — subscribe webhook

curl -X POST https://your-domain.com/api/v1/webhooks \
  -H "Authorization: Bearer 2pk_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "pass.scanned",
    "targetUrl": "https://example.com/hook"
  }'

JavaScript (fetch)

const response = await fetch("https://your-domain.com/api/v1/passes", {
  method: "POST",
  headers: {
    "Authorization": "Bearer 2pk_your_api_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    type: "single",
    name: "VIP Guest",
    customFields: [
      { key: "Full Name", value: "John Doe", isPublic: true }
    ],
  }),
});

const data = await response.json();
console.log(data.publicUrl);