Tvarka ATK API Pairing API
NFC remote pairing - complete a request by tapping a card on a different device.
NFC remote pairing - complete a request by tapping a card on a different device.
openapi: 3.2.0
info:
title: Tvarka Atk Pairing API
version: 1.3.0
description: 'Operations tagged Pairing across 2 of this provider''s published API definitions: tvarka-atk-api-auth-openapi.yaml, tvarka-atk-api-openapi-original.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://atk.tvarka.pro/v1
description: 'Production. Sandbox runs on the same host - provider credentials issued with
environment=sandbox get the identical API against test-card material and are never billed.
'
security:
- basicAuth: []
tags:
- name: Pairing
description: NFC remote pairing - complete a request by tapping a card on a different device.
paths:
/auth/{requestId}/pairing:
servers:
- url: https://atk.tvarka.pro/v1
description: 'Production. Sandbox runs on the same host - provider credentials issued with
environment=sandbox get the identical API against test-card material and are never billed.
'
get:
tags:
- Pairing
operationId: getAuthPairing
summary: Get a pairing token/QR to complete this request on a phone
description: 'Only for `method:"nfc"`. Basic only - the integrator''s server rotates the one-time token.
Returns a high-entropy, short-lived, one-claim pairing token and a deep link / QR the phone
scans. The phone then calls `/pairing/claim`, receives the request''s `clientToken`, and
drives the same `/certificate` + `/complete` endpoints.
'
security:
- basicAuth: []
parameters:
- $ref: '#/components/parameters/RequestId'
responses:
'200':
description: Pairing payload.
content:
application/json:
schema:
$ref: '#/components/schemas/PairingInfo'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
/pairing/claim:
servers:
- url: https://atk.tvarka.pro/v1
description: 'Production. Sandbox runs on the same host - provider credentials issued with
environment=sandbox get the identical API against test-card material and are never billed.
'
post:
tags:
- Pairing
operationId: claimPairing
summary: Claim a pairing token from the tapping phone
description: 'No Basic auth - authorized solely by the high-entropy `pairingToken`. One-claim, rate-limited,
stored hashed. Returns the request''s `clientToken` and a minimal `summary` (purpose + label
only, never document contents).
'
security: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/PairingClaimRequest'
responses:
'200':
description: Claimed.
content:
application/json:
schema:
$ref: '#/components/schemas/PairingClaimResponse'
'404':
$ref: '#/components/responses/NotFound'
'409':
$ref: '#/components/responses/Conflict'
'429':
$ref: '#/components/responses/RateLimited'
components:
responses:
Conflict:
description: State/idempotency conflict (spent operation token, identity swap, terminal request).
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
NotFound:
description: Unknown request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
RateLimited:
description: Too many requests.
headers:
Retry-After:
schema:
type: integer
description: Seconds.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
parameters:
RequestId:
name: requestId
in: path
required: true
description: The `requestId` returned by `POST /auth/requests`.
schema:
type: string
format: uuid
schemas:
PairingClaimRequest:
type: object
required:
- pairingToken
properties:
pairingToken:
type: string
minLength: 32
maxLength: 200
claimNonce:
type: string
maxLength: 120
description: Optional; when the originating UI can pre-share it, binds the tap to the intended session.
device:
type: object
additionalProperties: false
properties:
platform:
type: string
maxLength: 40
appVersion:
type: string
maxLength: 40
deviceName:
type: string
maxLength: 120
ErrorBody:
type: object
required:
- code
- message
properties:
code:
$ref: '#/components/schemas/ErrorCode'
message:
type: string
requestId:
type: string
format: uuid
retryable:
type: boolean
Error:
type: object
required:
- error
properties:
error:
$ref: '#/components/schemas/ErrorBody'
PairingInfo:
allOf:
- $ref: '#/components/schemas/PairingHint'
- type: object
required:
- pairingToken
- expiresAt
properties:
pairingToken:
type: string
description: High-entropy, one-claim, short-lived.
expiresAt:
type: string
format: date-time
PairingClaimResponse:
type: object
required:
- requestId
- purpose
- clientToken
- status
properties:
requestId:
type: string
format: uuid
purpose:
type: string
enum:
- auth
- sign
clientToken:
type: string
status:
$ref: '#/components/schemas/Status'
summary:
type: object
additionalProperties: true
description: Minimal display context {purpose, provider, audience, label, format?} - never document contents.
PairingHint:
type: object
properties:
pairingUrl:
type: string
format: uri
example: https://sign.tvarka.pro/atk-login/#PAIRING_TOKEN
deepLink:
type: string
example: tvarkasign://atk/pair/PAIRING_TOKEN
qrPayload:
type: string
example: https://sign.tvarka.pro/atk-login/#PAIRING_TOKEN
ErrorCode:
type: string
description: 'The full stable error-code catalog of the ATK API family (auth + sign + services);
each endpoint returns the subset that applies to it. By HTTP status:
400 invalid_json, missing_field, invalid_field, invalid_webhook_url, invalid_document_ref.
401 invalid_basic_credentials, invalid_client_token, client_token_expired,
operation_token_expired, invalid_download_token.
403 origin_not_allowed, ip_not_allowed, format_not_allowed, document_ref_host_not_allowed,
method_not_allowed, tenant_suspended, tier_forbidden.
404 request_not_found, pairing_not_found, document_not_ready.
409 request_terminal, operation_token_spent, identity_swap, idempotency_conflict,
service_in_progress, pairing_not_available, pairing_already_claimed.
410 pairing_expired. 413 document_too_large.
422 cert_invalid, untrusted_chain, cert_revoked, cert_expired, not_qualified,
cert_purpose_mismatch, signature_invalid, document_hash_mismatch, document_size_mismatch.
429 rate_limited. 500 assembly_failed. 502 document_ref_fetch_failed.
503 erasure_failed, pairing_service_unavailable, service_unavailable.
The catalog can grow in minor versions - fall back to HTTP status semantics
for codes you do not recognize.
'
enum:
- invalid_json
- missing_field
- invalid_field
- invalid_webhook_url
- invalid_document_ref
- invalid_basic_credentials
- invalid_client_token
- client_token_expired
- operation_token_expired
- invalid_download_token
- origin_not_allowed
- ip_not_allowed
- format_not_allowed
- document_ref_host_not_allowed
- method_not_allowed
- tenant_suspended
- tier_forbidden
- request_not_found
- pairing_not_found
- document_not_ready
- request_terminal
- operation_token_spent
- identity_swap
- idempotency_conflict
- service_in_progress
- pairing_not_available
- pairing_already_claimed
- pairing_expired
- document_too_large
- cert_invalid
- untrusted_chain
- cert_revoked
- cert_expired
- not_qualified
- cert_purpose_mismatch
- signature_invalid
- document_hash_mismatch
- document_size_mismatch
- rate_limited
- assembly_failed
- document_ref_fetch_failed
- erasure_failed
- pairing_service_unavailable
- service_unavailable
Status:
type: string
description: 'Flat request status. Non-terminal - `pending`, `awaitingCard`, `awaitingCredentials`,
`finalizing`. Terminal success - `done`. Terminal failure -
`cancelled`/`timeout`/`deviceError`/`pinBlocked`/`cardRemoved`/`certInvalid`.
`awaitingCredentials` is SDK-reported (CAN/PIN entry is out-of-band).
'
enum:
- pending
- awaitingCard
- awaitingCredentials
- finalizing
- done
- cancelled
- timeout
- deviceError
- pinBlocked
- cardRemoved
- certInvalid
securitySchemes:
basicAuth:
type: http
scheme: basic
description: 'Provider server-to-server credentials `keyId:keySecret`. Server-to-server only, also gated by the
provider''s server IP allow-list. Never placed in a browser/mobile client.
'
clientToken:
type: http
scheme: bearer
bearerFormat: JWT
description: 'Short-lived, per-request JWT (`ES256`) minted at request creation, scoped
`{tenant, requestId, purpose, method, allowedOrigins}`. Safe to hand to a browser/mobile client:
it cannot create requests, read tenant data, or touch other requests. For browser clients the API
enforces `Origin` against `allowedOrigins` (rejects cross-origin replay).
'
downloadToken:
type: apiKey
in: query
name: downloadToken
description: One-off token returned with a completed sign result, for fetching the signed document.
externalDocs:
description: Quickstart, SDKs, test data, pricing and lifecycle policy
url: https://atk.tvarka.pro/docs/
x-refined-from:
- tvarka-atk-api-auth-openapi.yaml
- tvarka-atk-api-openapi-original.json