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