{"openapi":"3.1.0","info":{"title":"eCMR Hub API","version":"0.3.0","description":"HTTP API of eCMR Hub. Every request sends the public `apikey` header and `Authorization: Bearer <access token>`: the token of an OAuth connection or of a company API key. The company comes from the token; there is no company header. Errors are JSON `{code, message}`, and `{error: {status, code, message, retryable, approval}}` from the approval gate; rely on `code`, messages may be in Polish. Production origin: https://api-ecmr-dev.lucaspiera.com. Provider signatures and eFTI gateway exchange are not available."},"jsonSchemaDialect":"https://json-schema.org/draft/2020-12/schema","servers":[{"url":"https://api-ecmr-dev.lucaspiera.com","description":"eCMR Hub production"}],"security":[{"apikey":[],"bearerAuth":[]}],"paths":{"/functions/v1/publish":{"post":{"operationId":"publishDraft","summary":"Issue a draft","parameters":[{"$ref":"#/components/parameters/Approval"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"draftId":{"type":"string","format":"uuid"},"revision":{"type":"integer","minimum":1}},"required":["draftId","revision"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Document"}}}},"428":{"$ref":"#/components/responses/ApprovalRefused"},"default":{"$ref":"#/components/responses/Problem"}},"description":"Issues one immutable document from a complete draft revision. Issuing the same draft again returns the same document. May need a person's approval.","tags":["drafts"]}},"/functions/v1/connections":{"get":{"operationId":"listConnections","summary":"List connections (a person only)","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Connection"}}},"required":["items"],"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"OAuth agents and programs and API keys of the company, on one list.","tags":["connections"]}},"/functions/v1/connections/{connectionId}":{"patch":{"operationId":"updateConnection","summary":"Change a connection (owner only)","parameters":[{"in":"path","name":"connectionId","schema":{"type":"string","format":"uuid"},"required":true}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"requireApproval":{"type":"boolean"},"permissions":{"maxItems":6,"type":"array","items":{"type":"string","enum":["documents:read","documents:write","library:read","library:write","signing:links","tracking:manage"]}}},"additionalProperties":false}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Connection"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Changes the permissions of a connection or whether its writes wait for a person's approval.","tags":["connections"]},"delete":{"operationId":"revokeConnection","summary":"Disconnect (owner only)","parameters":[{"in":"path","name":"connectionId","schema":{"type":"string","format":"uuid"},"required":true}],"responses":{"204":{"description":"Revoked"},"default":{"$ref":"#/components/responses/Problem"}},"description":"Revokes an API key, or disconnects an OAuth connection with its sessions and grant. Its pending approvals expire.","tags":["connections"]}},"/functions/v1/approvals":{"get":{"operationId":"listApprovals","summary":"List approvals","parameters":[{"in":"query","name":"status","schema":{"type":"string","enum":["pending","approved","rejected","consumed","expired"]}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/Approval"}}},"required":["items"],"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Approvals newest first, optionally by status. A person sees the whole company's; an OAuth connection or an API key sees only its own.","tags":["approvals"]}},"/functions/v1/approvals/{approvalId}":{"get":{"operationId":"getApproval","summary":"Read an approval","parameters":[{"in":"path","name":"approvalId","schema":{"type":"string","format":"uuid"},"required":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Approval"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"One approval with its status (pending, approved, rejected, consumed, expired). Poll it after 428 APPROVAL_REQUIRED, then repeat the call with the x-ecmr-approval header.","tags":["approvals"]}},"/functions/v1/approvals/{approvalId}/approve":{"post":{"operationId":"approveApproval","summary":"Approve (a person only)","parameters":[{"in":"path","name":"approvalId","schema":{"type":"string","format":"uuid"},"required":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Approval"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"A person of the company approves the call. Connections, API keys and the assistant are refused.","tags":["approvals"]}},"/functions/v1/approvals/{approvalId}/reject":{"post":{"operationId":"rejectApproval","summary":"Reject (a person only)","parameters":[{"in":"path","name":"approvalId","schema":{"type":"string","format":"uuid"},"required":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Approval"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"A person of the company rejects the call. Connections, API keys and the assistant are refused.","tags":["approvals"]}},"/functions/v1/sign/{token}":{"get":{"operationId":"getSignEvidence","summary":"Signer: read the document","security":[],"parameters":[{"in":"path","name":"token","schema":{"type":"string"},"required":true}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignEvidence"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Called by the person who opened a signing link, with its token. Expired or revoked links answer 410.","tags":["signer"]},"post":{"operationId":"submitSignConsent","summary":"Signer: sign","security":[],"parameters":[{"in":"path","name":"token","schema":{"type":"string"},"required":true}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceConsent"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"The signer's consent for one role and document digest, sent with the signing link token.","tags":["signer"]}},"/functions/v1/sign/{token}/pdf":{"get":{"operationId":"getSignPdf","summary":"Signer: download the PDF","security":[],"parameters":[{"in":"path","name":"token","schema":{"type":"string"},"required":true}],"responses":{"200":{"description":"The stored presentation PDF. X-Artifact-Sha256 carries its SHA-256; compare it with the bytes before showing them.","headers":{"X-Artifact-Sha256":{"required":true,"schema":{"type":"string"}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"The PDF the signer must be shown, read with the signing link token.","tags":["signer"]}},"/functions/v1/artifacts/{documentId}":{"get":{"operationId":"getDocumentPdf","summary":"Download the document PDF","parameters":[{"in":"path","name":"documentId","schema":{"type":"string","format":"uuid"},"required":true}],"responses":{"200":{"description":"The stored presentation PDF. X-Artifact-Sha256 carries its SHA-256; compare it with the bytes before showing them.","headers":{"X-Artifact-Sha256":{"required":true,"schema":{"type":"string"}}},"content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Presentation PDF of the current issued version, with its SHA-256.","tags":["documents"]}},"/rest/v1/type_definitions":{"get":{"operationId":"readTypeDefinitions","summary":"Read document types","security":[{"apikey":[]}],"parameters":[{"in":"query","name":"select","schema":{"default":"definition","type":"string"}},{"in":"query","name":"name","schema":{"description":"PostgREST equality filter: eq.<value>","type":"string"},"description":"PostgREST equality filter: eq.<value>"},{"in":"query","name":"version","schema":{"description":"PostgREST equality filter: eq.<value>","type":"string"},"description":"PostgREST equality filter: eq.<value>"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"definition":{"$ref":"#/components/schemas/TypeDefinition"}},"required":["definition"],"additionalProperties":false}}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Definitions of document types by name and version.","tags":["documents"]}},"/rest/v1/documents":{"get":{"operationId":"readDocuments","summary":"List documents","parameters":[{"in":"query","name":"select","schema":{"default":"body","type":"string"}},{"in":"query","name":"id","schema":{"description":"PostgREST equality filter: eq.<value>","type":"string"},"description":"PostgREST equality filter: eq.<value>"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"body":{"$ref":"#/components/schemas/Document"}},"required":["body"],"additionalProperties":false}}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Issued documents of the company. Returns an array; an id you cannot see returns an empty array.","tags":["documents"]}},"/rest/v1/versions":{"get":{"operationId":"readVersions","summary":"Read document versions","parameters":[{"in":"query","name":"select","schema":{"default":"body","type":"string"}},{"in":"query","name":"id","schema":{"description":"PostgREST equality filter: eq.<value>","type":"string"},"description":"PostgREST equality filter: eq.<value>"},{"in":"query","name":"document_id","schema":{"description":"PostgREST equality filter: eq.<value>","type":"string"},"description":"PostgREST equality filter: eq.<value>"}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"body":{"$ref":"#/components/schemas/DocumentVersion"}},"required":["body"],"additionalProperties":false}}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Immutable versions of a document. Returns an array; an id you cannot see returns an empty array.","tags":["documents"]}},"/rest/v1/rpc/evidence":{"post":{"operationId":"getEvidence","summary":"Read document evidence","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document_id":{"type":"string","format":"uuid"}},"required":["document_id"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceEvidence"}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Canonical evidence of a document: versions, events, signatures and the digest chain.","tags":["documents"]}},"/rest/v1/rpc/whoami":{"post":{"operationId":"whoami","summary":"Who am I","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"kind":{"type":"string","enum":["user","apikey","connection"]},"tenantId":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["owner","member"]},"keyId":{"type":"string","format":"uuid"},"name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string","enum":["documents:read","documents:write","library:read","library:write","signing:links","tracking:manage"]}},"expiresAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"connectionId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"clientId":{"type":"string"},"requireApproval":{"type":"boolean"}},"required":["kind","tenantId","permissions"],"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"The kind of caller (user, apikey or connection), its company, permissions and, for a connection or an API key, whether its writes wait for a person's approval.","tags":["connections"]}},"/rest/v1/rpc/save_draft":{"post":{"operationId":"save_draft","summary":"Save a draft","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"operation_id":{"type":"string","format":"uuid"},"draft_id":{"type":"string","format":"uuid"},"base_revision":{"type":"integer","minimum":0},"data":{"type":"object","additionalProperties":{}}},"required":["operation_id","draft_id","base_revision","data"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Creates a draft or saves a new revision. Send the revision you started from; a newer one on the server answers 409 VERSION_CONFLICT. The operation id makes a retry safe.","tags":["drafts"]}},"/rest/v1/rpc/delete_draft":{"post":{"operationId":"delete_draft","summary":"Delete a draft","parameters":[{"$ref":"#/components/parameters/Approval"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"operation_id":{"type":"string","format":"uuid"},"draft_id":{"type":"string","format":"uuid"},"base_revision":{"type":"integer","minimum":0}},"required":["operation_id","draft_id","base_revision"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","const":true}},"required":["id","deleted"],"additionalProperties":false}}}},"428":{"$ref":"#/components/responses/ApprovalRefused"},"default":{"$ref":"#/components/responses/Problem"}},"description":"Deletes a draft that was not issued. An issued document cannot be deleted (409 DRAFT_ISSUED). May need a person's approval.","tags":["drafts"]}},"/rest/v1/rpc/list_drafts":{"post":{"operationId":"list_drafts","summary":"List drafts","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"after":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"items":{"type":"array","items":{"type":"object","additionalProperties":{}}},"nextCursor":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]}},"required":["items","nextCursor"],"additionalProperties":false}}}},"default":{"$ref":"#/components/responses/Problem"}},"description":"Drafts of the company, newest first, one cursor page at a time.","tags":["drafts"]}},"/rest/v1/rpc/create_sign_grant":{"post":{"operationId":"create_sign_grant","summary":"Create a signing link","parameters":[{"$ref":"#/components/parameters/Approval"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document_id":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["sender","carrier","consignee"]},"idempotency_key":{"type":"string"}},"required":["document_id","role","idempotency_key"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","additionalProperties":{}}}}},"428":{"$ref":"#/components/responses/ApprovalRefused"},"default":{"$ref":"#/components/responses/Problem"}},"description":"Creates a signing link for one party of an issued document, valid for 7 days. Reuse the idempotency key on retry. May need a person's approval.","tags":["signing-links"]}},"/rest/v1/rpc/revoke_sign_grants":{"post":{"operationId":"revoke_sign_grants","summary":"Revoke the signing links of a document","parameters":[{"$ref":"#/components/parameters/Approval"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document_id":{"type":"string","format":"uuid"}},"required":["document_id"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}}},"428":{"$ref":"#/components/responses/ApprovalRefused"},"default":{"$ref":"#/components/responses/Problem"}},"description":"Revokes the signing links of a document. May need a person's approval.","tags":["signing-links"]}},"/rest/v1/rpc/revoke_sign_grant":{"post":{"operationId":"revoke_sign_grant","summary":"Revoke a signing link","parameters":[{"$ref":"#/components/parameters/Approval"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"document_id":{"type":"string","format":"uuid"},"role":{"type":"string","enum":["sender","carrier","consignee"]}},"required":["document_id","role"]}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"],"additionalProperties":false}}}},"428":{"$ref":"#/components/responses/ApprovalRefused"},"default":{"$ref":"#/components/responses/Problem"}},"description":"Revokes one signing link. May need a person's approval.","tags":["signing-links"]}}},"components":{"schemas":{"TypeRef":{"type":"object","properties":{"name":{"type":"string","pattern":"^[a-z][a-z0-9_-]{0,63}$"},"version":{"type":"string","minLength":1,"maxLength":200}},"required":["name","version"],"additionalProperties":false},"DeviceConsent":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentDigest":{"type":"string"},"artifactDigest":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of the presentation PDF the signer was shown (artifact of the current version)."},"role":{"type":"string","enum":["sender","carrier","consignee"]},"name":{"type":"string"},"statement":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"strokes":{"type":"array","items":{"type":"array","items":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"],"additionalProperties":false}},"description":"Drawn signature normalised to the unit square. Empty when mark says the signature was typed."},"mark":{"description":"Present only on a signature set from the typed name (profile evidence-0.3); it is rendered from name in the given style and labelled as signed electronically.","type":"object","properties":{"kind":{"type":"string","const":"typed"},"style":{"type":"string","const":"great-vibes"}},"required":["kind","style"],"additionalProperties":false},"reservations":{"description":"Reservations the consignee states on taking delivery (art. 30 CMR), at most 150 characters, printed in box 24. Only on a consignee consent and never empty; absent when there are none (profile evidence-0.5).","type":"string"},"photos":{"description":"Photos taken with the signature, signed by SHA-256 (profile evidence-0.7). At most 10, never empty, each hash once; absent when there are none. The bytes are uploaded separately to /consents/{documentId}/photos/{consentId}/{sha256} (or /sign/{token}/photos/... from a signing link) and stored only when they match.","type":"array","items":{"$ref":"#/components/schemas/ConsentPhoto"}},"publicKey":{"type":"object","additionalProperties":{}},"signature":{"type":"string","description":"Base64 ECDSA P-256 IEEE P1363 signature over canonical assertion excluding signature field."}},"required":["id","documentDigest","artifactDigest","role","name","statement","occurredAt","strokes","publicKey","signature"],"additionalProperties":false},"ConsentPhoto":{"type":"object","properties":{"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of the stored photo bytes."},"category":{"type":"string","enum":["goods","damage","customs","other"]},"addedAt":{"type":"string","format":"date-time","description":"When the photo was added to the signature, device clock."},"mediaType":{"type":"string","enum":["image/jpeg","image/png","image/webp"]},"byteSize":{"type":"integer","exclusiveMinimum":0,"maximum":1048576}},"required":["sha256","category","addedAt","mediaType","byteSize"],"additionalProperties":false},"Problem":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"],"description":"Edge errors use code and message. PostgREST may additionally include details and hint. Status is the HTTP response status. CONTRACT_VIOLATION (500) means the server produced a response that does not match this contract."},"Document":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"tenantId":{"type":"string","format":"uuid"},"type":{"$ref":"#/components/schemas/TypeRef"},"reference":{"type":"string","minLength":1,"maxLength":200},"currentVersionId":{"type":"string","format":"uuid"},"state":{"type":"string","minLength":1,"maxLength":200},"createdAt":{"type":"string","format":"date-time"}},"required":["id","tenantId","type","reference","currentVersionId","state","createdAt"],"additionalProperties":false,"description":"state is a server-derived value from the type state machine. It is never writable directly."},"ApprovalProblem":{"type":"object","properties":{"error":{"type":"object","properties":{"status":{"type":"integer"},"code":{"type":"string"},"message":{"type":"string"},"retryable":{"type":"boolean"},"approval":{"$ref":"#/components/schemas/ApprovalRef"}},"required":["status","code","message","retryable"],"additionalProperties":false}},"required":["error"],"additionalProperties":false},"ApprovalRef":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"url":{"type":"string"},"expiresAt":{"type":"string","format":"date-time"},"operation":{"type":"string"},"status":{"type":"string","enum":["pending","approved","rejected","consumed","expired"]}},"required":["id","url","expiresAt","operation","status"],"additionalProperties":false},"Connection":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kind":{"type":"string","enum":["oauth","apikey"]},"clientId":{"type":["string","null"]},"apiKeyId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"name":{"type":"string"},"permissions":{"type":"array","items":{"type":"string","enum":["documents:read","documents:write","library:read","library:write","signing:links","tracking:manage"]}},"requireApproval":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"},"lastUsedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"revokedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]}},"required":["id","kind","clientId","apiKeyId","name","permissions","requireApproval","createdAt","lastUsedAt","revokedAt"],"additionalProperties":false},"Approval":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"operation":{"type":"string"},"status":{"type":"string","enum":["pending","approved","rejected","consumed","expired"]},"requestedBy":{"type":"object","properties":{"connectionId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}]},"name":{"type":"string"}},"required":["connectionId","name"],"additionalProperties":false},"summary":{"anyOf":[{"$ref":"#/components/schemas/ApprovalCard"},{"type":"null"}]},"input":{"type":"object","additionalProperties":{}},"url":{"type":"string"},"createdAt":{"type":"string","format":"date-time"},"decidedAt":{"anyOf":[{"type":"string","format":"date-time"},{"type":"null"}]},"decidedBy":{"type":["string","null"]},"expiresAt":{"type":"string","format":"date-time"}},"required":["id","operation","status","requestedBy","summary","input","url","createdAt","decidedAt","decidedBy","expiresAt"],"additionalProperties":false},"ApprovalCard":{"type":"object","properties":{"subject":{"type":"string"},"action":{"type":"string"},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"}},"required":["id"]}},"batch":{"type":"object","properties":{"total":{"type":"integer"}},"required":["total"],"additionalProperties":false},"includesSave":{"type":"boolean"}},"required":["subject","action","items"]},"SignEvidence":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/Document"},"version":{"$ref":"#/components/schemas/DocumentVersion"},"consents":{"type":"array","items":{"type":"object","properties":{"body":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentDigest":{"type":"string"},"artifactDigest":{"description":"Absent on consents recorded before profile evidence-0.2.","type":"string","pattern":"^[a-f0-9]{64}$"},"role":{"type":"string","enum":["sender","carrier","consignee"]},"name":{"type":"string"},"statement":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"strokes":{"type":"array","items":{"type":"array","items":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"],"additionalProperties":false}},"description":"Drawn signature normalised to the unit square. Empty when mark says the signature was typed."},"mark":{"description":"Present only on a signature set from the typed name (profile evidence-0.3); it is rendered from name in the given style and labelled as signed electronically.","type":"object","properties":{"kind":{"type":"string","const":"typed"},"style":{"type":"string","const":"great-vibes"}},"required":["kind","style"],"additionalProperties":false},"reservations":{"description":"Reservations the consignee states on taking delivery (art. 30 CMR), at most 150 characters, printed in box 24. Only on a consignee consent and never empty; absent when there are none (profile evidence-0.5).","type":"string"},"photos":{"description":"Photos taken with the signature, signed by SHA-256 (profile evidence-0.7). At most 10, never empty, each hash once; absent when there are none. The bytes are uploaded separately to /consents/{documentId}/photos/{consentId}/{sha256} (or /sign/{token}/photos/... from a signing link) and stored only when they match.","type":"array","items":{"$ref":"#/components/schemas/ConsentPhoto"}},"publicKey":{"type":"object","additionalProperties":{}},"signature":{"type":"string","description":"Base64 ECDSA P-256 IEEE P1363 signature over canonical assertion excluding signature field."}},"required":["id","documentDigest","role","name","statement","occurredAt","strokes","publicKey","signature"],"additionalProperties":false},"receivedAt":{"type":"string"},"digest":{"type":"string"}},"required":["body","receivedAt","digest"]}},"events":{"type":"array","items":{"$ref":"#/components/schemas/ChainLink"}},"artifacts":{"type":"array","items":{"$ref":"#/components/schemas/Artifact"}},"timestamps":{"type":"array","items":{"$ref":"#/components/schemas/Timestamp"}},"olfSeals":{"type":"array","items":{"$ref":"#/components/schemas/OlfSeal"}},"photos":{"type":"array","items":{"$ref":"#/components/schemas/EvidencePhoto"}},"profile":{"type":"string"},"pades":{"type":"boolean","const":false},"role":{"type":"string","enum":["sender","carrier","consignee"]},"artifact":{"$ref":"#/components/schemas/Artifact"}},"required":["document","version","consents","events","artifacts","profile","pades","role","artifact"]},"DocumentVersion":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"revision":{"type":"integer","minimum":1},"type":{"$ref":"#/components/schemas/TypeRef"},"state":{"type":"string","minLength":1,"maxLength":200},"data":{"type":"object","additionalProperties":{}},"canonicalizationVersion":{"type":"string","minLength":1,"maxLength":200},"snapshotDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","documentId","revision","type","state","data","canonicalizationVersion","snapshotDigest","createdAt"],"additionalProperties":false,"description":"Immutable snapshot, including state and type version. The canonicalization profile defines the exact bytes; snapshotDigest is not a digital signature."},"ChainLink":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"name":{"type":["string","null"]},"payloadDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"},"previousDigest":{"anyOf":[{"type":"string","pattern":"^[a-f0-9]{64}$"},{"type":"null"}]},"eventDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"},"receivedAt":{"type":"string","format":"date-time"}},"required":["id","versionId","name","payloadDigest","previousDigest","eventDigest","receivedAt"],"additionalProperties":false},"Artifact":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentId":{"type":"string","format":"uuid"},"versionId":{"type":"string","format":"uuid"},"kind":{"type":"string","const":"presentation_pdf"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"byteSize":{"type":"integer","exclusiveMinimum":0},"renderer":{"type":"object","additionalProperties":{},"description":"Renderer, pdf-lib version and asset hashes that produced the stored bytes."},"createdAt":{"type":"string","format":"date-time"}},"required":["id","documentId","versionId","kind","sha256","byteSize","renderer","createdAt"],"additionalProperties":false,"description":"The one presentation PDF stored for a document version. The stored bytes are the evidence; rendering is not required to be byte-for-byte repeatable."},"Timestamp":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subjectKind":{"type":"string","const":"consent"},"subjectId":{"type":"string","format":"uuid"},"messageImprint":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of the timestamped data: the consent digest (JCS form of the consent)."},"tsa":{"type":"string","description":"Time-stamping authority identifier."},"token":{"type":"string","description":"RFC 3161 TimeStampToken (CMS ContentInfo with SignedData), DER, base64. Qualification is established by validating it against a trusted list."},"genTime":{"type":"string","format":"date-time"},"policy":{"type":"string"},"serial":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","subjectKind","subjectId","messageImprint","tsa","token","genTime","policy","serial","createdAt"],"additionalProperties":false,"description":"RFC 3161 time-stamp over a consent digest. A consent without one is still being timestamped."},"OlfSeal":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"ecmrId":{"type":"string","format":"uuid"},"position":{"type":"integer","minimum":1,"maximum":3},"role":{"type":"string","enum":["SENDER","CARRIER","CONSIGNEE"]},"versionId":{"anyOf":[{"type":"string","format":"uuid"},{"type":"null"}],"description":"The document version created from this seal's sealedDocument.ecmr; null while the source awaits approval."},"jws":{"type":"string","description":"The JAdES-B-B compact JWS exactly as received."},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"precedingSha256":{"anyOf":[{"type":"string","pattern":"^[a-f0-9]{64}$"},{"type":"null"}]},"alg":{"type":"string"},"x5tS256":{"type":"string"},"originUrl":{"type":"string"},"iat":{"type":["integer","null"]},"sealer":{"type":["string","null"]},"sealerCompany":{"type":["string","null"]},"origin":{"type":"string","enum":["ours","foreign"]},"receivedAt":{"type":"string","format":"date-time"},"verifications":{"type":"array","items":{"$ref":"#/components/schemas/OlfSealVerification"}},"timestamps":{"type":"array","items":{"$ref":"#/components/schemas/OlfSealTimestamp"}}},"required":["id","ecmrId","position","role","versionId","jws","sha256","precedingSha256","alg","x5tS256","originUrl","iat","sealer","sealerCompany","origin","receivedAt","verifications","timestamps"],"additionalProperties":false,"description":"One OLF eCMR eSeal of the document's chain, with every verification and time-stamp."},"OlfSealVerification":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"verifiedAt":{"type":"string","format":"date-time"},"result":{"type":"string","enum":["valid","invalid","indeterminate"]},"reason":{"type":["string","null"]},"dnsName":{"type":["string","null"]},"dnsAnswer":{"type":"array","items":{"type":"string"},"description":"Every TXT record found at dnsName when the seal was verified."},"verifierVersion":{"type":"string"}},"required":["id","verifiedAt","result","reason","dnsName","dnsAnswer","verifierVersion"],"additionalProperties":false},"OlfSealTimestamp":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"subjectKind":{"type":"string","const":"olf_seal"},"subjectId":{"type":"string","format":"uuid"},"messageImprint":{"type":"string","pattern":"^[a-f0-9]{64}$","description":"SHA-256 of the timestamped data: the bytes of the compact JWS after trimming, equal to the seal sha256."},"tsa":{"type":"string","description":"Time-stamping authority identifier."},"token":{"type":"string","description":"RFC 3161 TimeStampToken (CMS ContentInfo with SignedData), DER, base64. Qualification is established by validating it against a trusted list."},"genTime":{"type":"string","format":"date-time"},"policy":{"type":"string"},"serial":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}},"required":["id","subjectKind","subjectId","messageImprint","tsa","token","genTime","policy","serial","createdAt"],"additionalProperties":false,"description":"RFC 3161 time-stamp over the bytes of one OLF eSeal."},"EvidencePhoto":{"type":"object","properties":{"consentId":{"type":"string","format":"uuid"},"sha256":{"type":"string","pattern":"^[a-f0-9]{64}$"},"mediaType":{"type":"string","enum":["image/jpeg","image/png","image/webp"]},"byteSize":{"type":"integer","exclusiveMinimum":0},"receivedAt":{"type":"string","format":"date-time"}},"required":["consentId","sha256","mediaType","byteSize","receivedAt"],"additionalProperties":false,"description":"Bytes of one consent photo held by the server, verified against its SHA-256. A photo named by a consent but missing here has not been uploaded yet."},"TypeDefinition":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/TypeRef"},"dataSchema":{"type":"object","additionalProperties":{},"description":"JSON Schema 2020-12 for this immutable type version. Type definitions are authored by the platform, not clients."},"eventNames":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"uniqueItems":true},"signingPolicyIds":{"type":"array","items":{"type":"string","minLength":1,"maxLength":200},"uniqueItems":true},"schemaDigest":{"type":"string","pattern":"^[a-f0-9]{64}$"}},"required":["type","dataSchema","eventNames","signingPolicyIds","schemaDigest"],"additionalProperties":false},"DeviceEvidence":{"type":"object","properties":{"document":{"$ref":"#/components/schemas/Document"},"version":{"$ref":"#/components/schemas/DocumentVersion"},"consents":{"type":"array","items":{"type":"object","properties":{"body":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"documentDigest":{"type":"string"},"artifactDigest":{"description":"Absent on consents recorded before profile evidence-0.2.","type":"string","pattern":"^[a-f0-9]{64}$"},"role":{"type":"string","enum":["sender","carrier","consignee"]},"name":{"type":"string"},"statement":{"type":"string"},"occurredAt":{"type":"string","format":"date-time"},"strokes":{"type":"array","items":{"type":"array","items":{"type":"object","properties":{"x":{"type":"number"},"y":{"type":"number"}},"required":["x","y"],"additionalProperties":false}},"description":"Drawn signature normalised to the unit square. Empty when mark says the signature was typed."},"mark":{"description":"Present only on a signature set from the typed name (profile evidence-0.3); it is rendered from name in the given style and labelled as signed electronically.","type":"object","properties":{"kind":{"type":"string","const":"typed"},"style":{"type":"string","const":"great-vibes"}},"required":["kind","style"],"additionalProperties":false},"reservations":{"description":"Reservations the consignee states on taking delivery (art. 30 CMR), at most 150 characters, printed in box 24. Only on a consignee consent and never empty; absent when there are none (profile evidence-0.5).","type":"string"},"photos":{"description":"Photos taken with the signature, signed by SHA-256 (profile evidence-0.7). At most 10, never empty, each hash once; absent when there are none. The bytes are uploaded separately to /consents/{documentId}/photos/{consentId}/{sha256} (or /sign/{token}/photos/... from a signing link) and stored only when they match.","type":"array","items":{"$ref":"#/components/schemas/ConsentPhoto"}},"publicKey":{"type":"object","additionalProperties":{}},"signature":{"type":"string","description":"Base64 ECDSA P-256 IEEE P1363 signature over canonical assertion excluding signature field."}},"required":["id","documentDigest","role","name","statement","occurredAt","strokes","publicKey","signature"],"additionalProperties":false},"receivedAt":{"type":"string"},"digest":{"type":"string"}},"required":["body","receivedAt","digest"]}},"events":{"type":"array","items":{"$ref":"#/components/schemas/ChainLink"}},"artifacts":{"type":"array","items":{"$ref":"#/components/schemas/Artifact"}},"timestamps":{"type":"array","items":{"$ref":"#/components/schemas/Timestamp"}},"olfSeals":{"type":"array","items":{"$ref":"#/components/schemas/OlfSeal"}},"photos":{"type":"array","items":{"$ref":"#/components/schemas/EvidencePhoto"}},"profile":{"type":"string"},"pades":{"type":"boolean","const":false}},"required":["document","version","consents","events","artifacts","profile","pades"]}},"responses":{"Problem":{"description":"Request rejected; code and message describe the failure.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"ApprovalRefused":{"description":"Approval gate of a connection with requireApproval: 428 APPROVAL_REQUIRED (ask the person at approval.url, then repeat the same request with x-ecmr-approval), 409 APPROVAL_MISMATCH or APPROVAL_CONSUMED, 403 APPROVAL_REJECTED, 410 APPROVAL_EXPIRED, 404 APPROVAL_NOT_FOUND, 429 APPROVAL_LIMIT.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApprovalProblem"}}}}},"parameters":{"Approval":{"in":"header","name":"x-ecmr-approval","schema":{"description":"Id of the approval a person gave for exactly this request. Omitted: a connection that requires approval gets 428 APPROVAL_REQUIRED and the approval to ask for.","type":"string","format":"uuid"},"description":"Id of the approval a person gave for exactly this request. Omitted: a connection that requires approval gets 428 APPROVAL_REQUIRED and the approval to ask for."}},"securitySchemes":{"apikey":{"type":"apiKey","in":"header","name":"apikey"},"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}},"tags":[{"name":"drafts","description":"Create, update, list and delete consignment note drafts, then issue one.","x-displayName":"Drafts"},{"name":"documents","description":"Issued documents, their immutable versions, PDFs and evidence packages.","x-displayName":"Documents"},{"name":"signing-links","description":"Links a party (sender, carrier, consignee) opens to sign an issued document.","x-displayName":"Signing links"},{"name":"approvals","description":"Approvals a connection asked a person for. A connection reads its own; only a person approves or rejects, in the dashboard.","x-displayName":"Approvals"},{"name":"connections","description":"Who the token belongs to, and the OAuth agents and API keys connected to the company. Only a person manages connections.","x-displayName":"Connections and identity"},{"name":"signer","description":"Called with the token from a signing link by the person who signs. Agents do not call them.","x-displayName":"Signer endpoints"}]}