{"openapi":"3.0.3","info":{"title":"eCMR API","version":"1.0.0","description":"REST API for creating, issuing, signing and sharing electronic consignment\nnotes, built by 40 PÉS.\n\nCompliant with the CMR Convention, eIDAS (EU 910/2014) and GDPR (EU 2016/679).\n\n## Response envelope\n\nEvery JSON response uses the same envelope. On success:\n\n    { \"success\": true, \"data\": { ... }, \"meta\": { \"timestamp\": \"...\" } }\n\nOn failure:\n\n    { \"success\": false,\n      \"error\": { \"code\": \"...\", \"message\": \"...\", \"details\": [] },\n      \"meta\": { \"timestamp\": \"...\" } }\n\nEndpoints that return a PDF are the only exception; they answer with\n`application/pdf`.\n\n## Authentication\n\nTenant endpoints take an `X-API-Key` header. Reseller endpoints take an\n`X-Master-API-Key` header. Signup, verification, health and the public\nsignature view need no credentials.\n\n## Languages\n\nDocuments and emails are produced in Portuguese, English, Spanish, German,\nFrench or Italian, resolved from the tenant's `default_locale`.\n","contact":{"name":"40 PÉS","email":"info@40pes.pt","url":"https://40pes.pt"},"license":{"name":"Proprietary"}},"servers":[{"url":"https://ecmr.40pes.pt/api/v1/ecmr","description":"Production"},{"url":"https://ecmr.dev.40pes.pt/api/v1/ecmr","description":"Development"}],"tags":[{"name":"Status","description":"Health and version, no authentication."},{"name":"Signup","description":"Public tenant registration and email verification."},{"name":"Reseller signup","description":"Public reseller registration and email verification."},{"name":"Tenant","description":"The authenticated tenant's own profile, usage and webhook."},{"name":"Documents","description":"Create, read, update and search eCMR documents."},{"name":"Lifecycle","description":"Move a document between draft, issued, delivered and cancelled."},{"name":"Signatures","description":"Request, validate and collect signatures from the three parties."},{"name":"Shares","description":"Tokenised links and QR codes giving access to a document."},{"name":"Reseller","description":"Partner endpoints for managing sub-tenants and billing."}],"security":[{"ApiKeyAuth":[]}],"paths":{"/health":{"get":{"tags":["Status"],"summary":"Service health","operationId":"getHealth","description":"Reports the status of the API, the database and the PDF service.","security":[],"responses":{"200":{"description":"Health report.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","example":"healthy"},"service":{"type":"string"},"version":{"type":"string"},"timestamp":{"type":"string","format":"date-time"},"checks":{"type":"object"}}}}}},"503":{"description":"One or more checks failed."}}}},"/version":{"get":{"tags":["Status"],"summary":"API version","operationId":"getVersion","security":[],"responses":{"200":{"description":"Version and supported API versions.","content":{"application/json":{"schema":{"type":"object","properties":{"api_version":{"type":"string"},"supported_versions":{"type":"array","items":{"type":"string"}},"deprecations":{"type":"array","items":{"type":"string"}},"changelog_url":{"type":"string","format":"uri"}}}}}}}}},"/openapi":{"get":{"tags":["Status"],"summary":"This specification","operationId":"getOpenapi","description":"Serves this document, so a client can fetch the contract from the\nenvironment it is actually talking to. Request `openapi.yaml` or\n`openapi.json`.\n","security":[],"responses":{"200":{"description":"The OpenAPI specification.","content":{"application/yaml":{"schema":{"type":"string"}},"application/json":{"schema":{"type":"object"}}}}}}},"/signup":{"post":{"tags":["Signup"],"summary":"Register a company","operationId":"postSignup","description":"Creates a tenant in `pending_verification` and emails a verification\nlink. The API key is issued only once the email is verified.\n","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignupRequest"}}}},"responses":{"201":{"description":"Tenant created, verification email sent.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/SignupResult"}}}]}}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/signup/verify":{"get":{"tags":["Signup"],"summary":"Verify a company's email","operationId":"getSignupVerify","description":"Activates the tenant and returns its API key. This is the only moment\nthe key is shown in full. Requested with `Accept: text/html` it renders\na confirmation page instead.\n","security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"Token from the verification email. Valid for 24 hours."}],"responses":{"200":{"description":"Email verified, tenant active.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/VerifiedTenant"}}}]}},"text/html":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"410":{"description":"The token has expired. Request a new one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/signup/resend_verification":{"post":{"tags":["Signup"],"summary":"Resend the verification email","operationId":"postSignupResendVerification","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Verification email sent again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/tenant/profile":{"get":{"tags":["Tenant"],"summary":"Read the tenant profile","operationId":"getTenantProfile","responses":{"200":{"description":"The authenticated tenant.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"put":{"tags":["Tenant"],"summary":"Update the tenant profile","operationId":"putTenantProfile","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantUpdate"}}}},"responses":{"200":{"description":"Profile updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/tenant/usage":{"get":{"tags":["Tenant"],"summary":"Usage statistics","operationId":"getTenantUsage","description":"Document counts and API consumption for the current tenant.","responses":{"200":{"description":"Usage figures.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TenantUsage"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/tenant/webhook":{"get":{"tags":["Tenant"],"summary":"Read the webhook configuration","operationId":"getTenantWebhook","responses":{"200":{"description":"Current webhook settings.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"put":{"tags":["Tenant"],"summary":"Update the webhook configuration","operationId":"putTenantWebhook","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdate"}}}},"responses":{"200":{"description":"Webhook updated. A secret is generated when a URL is set.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/tenant/test_webhook":{"post":{"tags":["Tenant"],"summary":"Send a test event to the webhook","operationId":"postTenantTestWebhook","responses":{"200":{"description":"Test delivery attempted; the result describes the outcome.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents":{"get":{"tags":["Documents"],"summary":"List documents","operationId":"getDocuments","parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/DocumentStatus"}},{"name":"external_reference","in":"query","schema":{"type":"string"}},{"name":"created_after","in":"query","schema":{"type":"string","format":"date"}},{"name":"created_before","in":"query","schema":{"type":"string","format":"date"}},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"},{"name":"sort_by","in":"query","schema":{"type":"string"}},{"name":"sort_order","in":"query","schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"A page of documents.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentSummary"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Documents"],"summary":"Create a document","operationId":"postDocuments","description":"The document is created as `draft`. Issue it to make it effective.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["document"],"properties":{"document":{"$ref":"#/components/schemas/DocumentInput"}}}}}},"responses":{"201":{"description":"Document created.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Document"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/search":{"get":{"tags":["Documents"],"summary":"Search documents","operationId":"getDocumentsSearch","parameters":[{"name":"q","in":"query","required":true,"schema":{"type":"string"},"description":"Free text matched against CMR number, references and party names."},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"}],"responses":{"200":{"description":"Matching documents.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DocumentSummary"}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/documents/statistics":{"get":{"tags":["Documents"],"summary":"Document statistics","operationId":"getDocumentsStatistics","description":"Counts by status and recent activity for the current tenant.","responses":{"200":{"description":"Statistics.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/DocumentStatistics"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/documents/validate":{"post":{"tags":["Documents"],"summary":"Validate a payload without creating anything","operationId":"postDocumentsValidate","description":"Runs the same validation as create and reports what would fail.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["document"],"properties":{"document":{"$ref":"#/components/schemas/DocumentInput"}}}}}},"responses":{"200":{"description":"Validation result.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"valid":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Documents"],"summary":"Read a document","operationId":"getDocumentsByCmrNumber","responses":{"200":{"description":"The document.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Document"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Documents"],"summary":"Replace a document","operationId":"putDocumentsByCmrNumber","description":"Which fields may change depends on the status. A signed document\naccepts only the observation fields of parties that have not signed.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["document"],"properties":{"document":{"$ref":"#/components/schemas/DocumentInput"}}}}}},"responses":{"200":{"description":"Document updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Document"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}},"patch":{"tags":["Documents"],"summary":"Update a document","operationId":"patchDocumentsByCmrNumber","description":"Same rules as PUT; send only the fields you are changing.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["document"],"properties":{"document":{"$ref":"#/components/schemas/DocumentInput"}}}}}},"responses":{"200":{"description":"Document updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Document"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}},"delete":{"tags":["Documents"],"summary":"Delete a document","operationId":"deleteDocumentsByCmrNumber","description":"Only a draft can be deleted. Issued documents are cancelled instead.","responses":{"200":{"description":"Document deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/pdf":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Documents"],"summary":"Download the PDF","operationId":"getDocumentsByCmrNumberPdf","parameters":[{"name":"locale","in":"query","schema":{"$ref":"#/components/schemas/Locale"},"description":"Overrides the tenant's default language."},{"name":"bilingual","in":"query","schema":{"type":"boolean"},"description":"Renders the document in the chosen language alongside English."}],"responses":{"200":{"description":"The consignment note as a PDF.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/pdf/{role}":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"name":"role","in":"path","required":true,"schema":{"$ref":"#/components/schemas/SignatoryRole"}}],"get":{"tags":["Documents"],"summary":"Download the PDF as it stood for one party","operationId":"getDocumentsByCmrNumberPdfByRole","description":"The snapshot taken when that party signed, which is what they legally\nagreed to rather than the current state.\n","responses":{"200":{"description":"The snapshot as a PDF.","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/history":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Documents"],"summary":"Audit trail","operationId":"getDocumentsByCmrNumberHistory","description":"Every recorded change, signature and share, in order.","responses":{"200":{"description":"The audit trail.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/compliance":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Documents"],"summary":"Compliance report","operationId":"getDocumentsByCmrNumberCompliance","description":"Checks the document against the CMR Convention and eIDAS requirements.","responses":{"200":{"description":"The compliance report.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ComplianceReport"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/lifecycle/issue":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"post":{"tags":["Lifecycle"],"summary":"Issue a document","operationId":"postDocumentsByCmrNumberLifecycleIssue","description":"Moves a draft to `issued`, after which it can be signed.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"location":{"type":"string","description":"Where the transition happened."}}}}}},"responses":{"200":{"description":"Document issued.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LifecycleStatus"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/lifecycle/cancel":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"post":{"tags":["Lifecycle"],"summary":"Cancel a document","operationId":"postDocumentsByCmrNumberLifecycleCancel","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"location":{"type":"string"},"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Document cancelled.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LifecycleStatus"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/lifecycle/status":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Lifecycle"],"summary":"Lifecycle status","operationId":"getDocumentsByCmrNumberLifecycleStatus","description":"Current status, which transitions are allowed, and signature progress.","responses":{"200":{"description":"The lifecycle status.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/LifecycleStatus"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/signatures":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Signatures"],"summary":"List signatures","operationId":"getDocumentsByCmrNumberSignatures","responses":{"200":{"description":"Signatures on the document.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Signature"}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Signatures"],"summary":"Request a signature","operationId":"postDocumentsByCmrNumberSignatures","description":"For `remote`, the signatory receives a link by email or SMS and\nvalidates a one-time code before signing. For `in_person`, the\nsignature is captured on the device holding the document.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignatureRequest"}}}},"responses":{"201":{"description":"Signature requested.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/RequestedSignature"}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/signatures/{id}":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/SignatureId"}],"get":{"tags":["Signatures"],"summary":"Read a signature","operationId":"getDocumentsByCmrNumberSignaturesById","responses":{"200":{"description":"The signature.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Signature"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/signatures/{id}/validate_otp":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/SignatureId"}],"post":{"tags":["Signatures"],"summary":"Validate the one-time code","operationId":"postDocumentsByCmrNumberSignaturesByIdValidateOtp","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["otp_code"],"properties":{"otp_code":{"type":"string","description":"The code sent to the signatory."}}}}}},"responses":{"200":{"description":"Code accepted; the signature may now be captured.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Signature"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/signatures/{id}/sign":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/SignatureId"}],"post":{"tags":["Signatures"],"summary":"Sign","operationId":"postDocumentsByCmrNumberSignaturesByIdSign","description":"Records the signature and takes an immutable snapshot of the document\nas it stood. Send either a drawn signature or a certificate.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignPayload"}}}},"responses":{"200":{"description":"Signed.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Signature"}}}]}}}},"400":{"$ref":"#/components/responses/BadRequest"},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/signatures/{id}/cancel":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/SignatureId"}],"post":{"tags":["Signatures"],"summary":"Cancel a signature request","operationId":"postDocumentsByCmrNumberSignaturesByIdCancel","responses":{"200":{"description":"Request cancelled.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/signatures/{id}/resend_otp":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/SignatureId"}],"post":{"tags":["Signatures"],"summary":"Resend the one-time code","operationId":"postDocumentsByCmrNumberSignaturesByIdResendOtp","responses":{"200":{"description":"A new code was sent.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/shares":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Shares"],"summary":"List shares","operationId":"getDocumentsByCmrNumberShares","responses":{"200":{"description":"Every share created for the document.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Share"}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Shares"],"summary":"Create a share","operationId":"postDocumentsByCmrNumberShares","description":"Produces a tokenised link. `view` grants read-only access; `carrier`\nadditionally allows assigning a driver and requesting signatures.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["share"],"properties":{"share":{"$ref":"#/components/schemas/ShareInput"}}}}}},"responses":{"201":{"description":"Share created.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Share"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/shares/active":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"get":{"tags":["Shares"],"summary":"List active shares","operationId":"getDocumentsByCmrNumberSharesActive","description":"Shares that have not expired and have not been revoked.","responses":{"200":{"description":"Active shares.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Share"}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/shares/generate_qr":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"}],"post":{"tags":["Shares"],"summary":"Generate a QR code","operationId":"postDocumentsByCmrNumberSharesGenerateQr","description":"A QR code for a share link, for printing or showing at a checkpoint.","requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"share":{"$ref":"#/components/schemas/ShareInput"}}}}}},"responses":{"200":{"description":"The QR code, as a data URI, and the URL behind it.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"object","properties":{"share":{"$ref":"#/components/schemas/Share"},"qr_code_url":{"type":"string","format":"uri"},"qr_code_svg":{"type":"string","description":"The QR code as SVG markup."},"qr_code_base64":{"type":"string","description":"The QR code as a base64 PNG."}}}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/documents/{cmr_number}/shares/{token}":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/ShareToken"}],"get":{"tags":["Shares"],"summary":"Read a share","operationId":"getDocumentsByCmrNumberSharesByToken","responses":{"200":{"description":"The share.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Share"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/documents/{cmr_number}/shares/{token}/revoke":{"parameters":[{"$ref":"#/components/parameters/CmrNumber"},{"$ref":"#/components/parameters/ShareToken"}],"post":{"tags":["Shares"],"summary":"Revoke a share","operationId":"postDocumentsByCmrNumberSharesByTokenRevoke","description":"The link stops working immediately.","responses":{"200":{"description":"Share revoked.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/signatures/public/{token}":{"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"The public token from a signature request."}],"get":{"tags":["Signatures"],"summary":"Read a signature request by public token","operationId":"getSignaturesPublicByToken","description":"Used by the signing page. Returns only what the signatory needs to see,\nwith no tenant credentials.\n","security":[],"responses":{"200":{"description":"The signature request.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Signature"}}}]}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/reseller/signup":{"post":{"tags":["Reseller signup"],"summary":"Register as a reseller","operationId":"postResellerSignup","description":"Creates a reseller in `pending_verification` and emails a verification\nlink. The master API key is issued once the email is verified.\n","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResellerSignupRequest"}}}},"responses":{"201":{"description":"Reseller created, verification email sent.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResellerSignupResult"}}}]}}}},"422":{"$ref":"#/components/responses/ValidationFailed"},"429":{"$ref":"#/components/responses/RateLimited"}}}},"/reseller/signup/verify":{"get":{"tags":["Reseller signup"],"summary":"Verify a reseller's email","operationId":"getResellerSignupVerify","description":"Activates the reseller and returns the master API key. This is the only\nmoment the key is shown in full; afterwards it is masked.\n","security":[],"parameters":[{"name":"token","in":"query","required":true,"schema":{"type":"string"},"description":"Token from the verification email. Valid for 24 hours."}],"responses":{"200":{"description":"Email verified, reseller active.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/VerifiedReseller"}}}]}},"text/html":{"schema":{"type":"string"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"},"410":{"description":"The token has expired. Request a new one.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}}}},"/reseller/signup/resend_verification":{"post":{"tags":["Reseller signup"],"summary":"Resend the reseller verification email","operationId":"postResellerSignupResendVerification","security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email"}}}}}},"responses":{"200":{"description":"Verification email sent again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"400":{"$ref":"#/components/responses/BadRequest"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/reseller/profile":{"get":{"tags":["Reseller"],"summary":"Read the reseller profile","operationId":"getResellerProfile","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"The reseller. The master API key comes back masked.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Reseller"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"put":{"tags":["Reseller"],"summary":"Replace the reseller profile","operationId":"putResellerProfile","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResellerUpdate"}}}},"responses":{"200":{"description":"Profile updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Reseller"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}},"patch":{"tags":["Reseller"],"summary":"Update the reseller profile","operationId":"patchResellerProfile","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResellerUpdate"}}}},"responses":{"200":{"description":"Profile updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Reseller"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/tenants":{"get":{"tags":["Reseller"],"summary":"List sub-tenants","operationId":"getResellerTenants","security":[{"MasterApiKeyAuth":[]}],"parameters":[{"name":"status","in":"query","schema":{"$ref":"#/components/schemas/AccountStatus"}},{"$ref":"#/components/parameters/Page"},{"$ref":"#/components/parameters/PerPage"}],"responses":{"200":{"description":"A page of sub-tenants.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Tenant"}},"meta":{"$ref":"#/components/schemas/PaginationMeta"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Reseller"],"summary":"Create a sub-tenant","operationId":"postResellerTenants","description":"The tenant is created active, with no email verification, and its API\nkey is returned once. The reseller vouches for the company.\n","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResellerTenantInput"}}}},"responses":{"201":{"description":"Sub-tenant created.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TenantWithKey"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/tenants/{tenant_id}":{"parameters":[{"$ref":"#/components/parameters/TenantId"}],"get":{"tags":["Reseller"],"summary":"Read a sub-tenant","operationId":"getResellerTenantsByTenantId","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"The sub-tenant.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"put":{"tags":["Reseller"],"summary":"Replace a sub-tenant","operationId":"putResellerTenantsByTenantId","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResellerTenantUpdate"}}}},"responses":{"200":{"description":"Sub-tenant updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}},"patch":{"tags":["Reseller"],"summary":"Update a sub-tenant","operationId":"patchResellerTenantsByTenantId","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResellerTenantUpdate"}}}},"responses":{"200":{"description":"Sub-tenant updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}},"delete":{"tags":["Reseller"],"summary":"Delete a sub-tenant","operationId":"deleteResellerTenantsByTenantId","description":"Refused while the tenant still holds documents; suspend it instead.","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"Sub-tenant deleted.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/tenants/{tenant_id}/suspend":{"parameters":[{"$ref":"#/components/parameters/TenantId"}],"post":{"tags":["Reseller"],"summary":"Suspend a sub-tenant","operationId":"postResellerTenantsByTenantIdSuspend","description":"Its API key stops working; its documents are kept.","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"Sub-tenant suspended.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/tenants/{tenant_id}/activate":{"parameters":[{"$ref":"#/components/parameters/TenantId"}],"post":{"tags":["Reseller"],"summary":"Activate a sub-tenant","operationId":"postResellerTenantsByTenantIdActivate","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"Sub-tenant activated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/Tenant"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/tenants/{tenant_id}/regenerate_api_key":{"parameters":[{"$ref":"#/components/parameters/TenantId"}],"post":{"tags":["Reseller"],"summary":"Regenerate a sub-tenant's API key","operationId":"postResellerTenantsByTenantIdRegenerateApiKey","description":"The previous key stops working immediately. The new one is returned once.","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"A new API key was issued.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/TenantWithKey"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/webhook":{"get":{"tags":["Reseller"],"summary":"Read the reseller webhook configuration","operationId":"getResellerWebhook","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"Current webhook settings.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"put":{"tags":["Reseller"],"summary":"Replace the reseller webhook configuration","operationId":"putResellerWebhook","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdate"}}}},"responses":{"200":{"description":"Webhook updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}},"patch":{"tags":["Reseller"],"summary":"Update the reseller webhook configuration","operationId":"patchResellerWebhook","security":[{"MasterApiKeyAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookUpdate"}}}},"responses":{"200":{"description":"Webhook updated.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WebhookConfig"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/webhook/test":{"post":{"tags":["Reseller"],"summary":"Send a test event to the reseller webhook","operationId":"postResellerWebhookTest","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"Test delivery attempted; the result describes the outcome.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessEnvelope"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"422":{"$ref":"#/components/responses/ValidationFailed"}}}},"/reseller/billing":{"get":{"tags":["Reseller"],"summary":"Billing settings","operationId":"getResellerBilling","security":[{"MasterApiKeyAuth":[]}],"responses":{"200":{"description":"Billing configuration for the reseller.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResellerBilling"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/reseller/billing/usage":{"get":{"tags":["Reseller"],"summary":"Aggregated usage across sub-tenants","operationId":"getResellerBillingUsage","security":[{"MasterApiKeyAuth":[]}],"parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date"}},{"name":"to","in":"query","schema":{"type":"string","format":"date"}}],"responses":{"200":{"description":"Usage per sub-tenant and in total.","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SuccessEnvelope"},{"type":"object","properties":{"data":{"$ref":"#/components/schemas/ResellerBillingUsage"}}}]}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"A tenant's API key, issued on email verification."},"MasterApiKeyAuth":{"type":"apiKey","in":"header","name":"X-Master-API-Key","description":"A reseller's master API key, issued on email verification."}},"parameters":{"CmrNumber":{"name":"cmr_number","in":"path","required":true,"schema":{"type":"string"},"description":"The document's CMR number.","example":"CMR-2026-000123"},"SignatureId":{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"The signature's identifier."},"ShareToken":{"name":"token","in":"path","required":true,"schema":{"type":"string"},"description":"The share token."},"TenantId":{"name":"tenant_id","in":"path","required":true,"schema":{"type":"string"},"description":"The sub-tenant's identifier.","example":"tnt_8f2c4b1a9d3e5f70"},"Page":{"name":"page","in":"query","schema":{"type":"integer","minimum":1,"default":1}},"PerPage":{"name":"per_page","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}},"responses":{"BadRequest":{"description":"The request was malformed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"Unauthorized":{"description":"The API key is missing, unknown or belongs to a suspended account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"NotFound":{"description":"No such resource for this account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"ValidationFailed":{"description":"The payload was rejected; `details` lists what failed.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}},"RateLimited":{"description":"Too many requests.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorEnvelope"}}}}},"schemas":{"Meta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"}}},"SuccessEnvelope":{"type":"object","required":["success"],"properties":{"success":{"type":"boolean","description":"Always `true` on a successful response."},"data":{},"meta":{"$ref":"#/components/schemas/Meta"}}},"ErrorEnvelope":{"type":"object","required":["success","error"],"properties":{"success":{"type":"boolean","description":"Always `false` on an error response."},"error":{"type":"object","properties":{"code":{"type":"string","description":"A stable machine-readable code, such as `AUTH_INVALID_API_KEY`,\n`DOCUMENT_NOT_FOUND`, `VALIDATION_FAILED`, `LIFECYCLE_INVALID_TRANSITION`,\n`OTP_INVALID`, `SHARE_EXPIRED`, `ENDPOINT_NOT_FOUND` or `INTERNAL_ERROR`.\n"},"message":{"type":"string"},"details":{"type":"array","items":{"type":"string"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}},"PaginationMeta":{"type":"object","properties":{"timestamp":{"type":"string","format":"date-time"},"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}}},"Locale":{"type":"string","enum":["pt","en","es","de","fr","it"]},"AccountStatus":{"type":"string","enum":["pending_verification","active","suspended"]},"CompanyType":{"type":"string","enum":["consignor","consignee","carrier"]},"DocumentStatus":{"type":"string","enum":["draft","issued","accepted","delivered","completed","cancelled"]},"SignatoryRole":{"type":"string","enum":["consignor","carrier","consignee"]},"SignatureType":{"type":"string","enum":["remote","in_person","without_signature"]},"SignatureStatus":{"type":"string","enum":["pending","otp_sent","otp_validated","completed","cancelled"]},"SharePermission":{"type":"string","enum":["view","carrier"]},"Party":{"type":"object","description":"One of the three parties to the consignment note. When the tenant is\nitself one of the parties, the platform fills that party in from the\ntenant profile and rejects the fields you send for it.\n","properties":{"name":{"type":"string"},"address":{"type":"string"},"city":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string","description":"ISO 3166-1 alpha-2."},"vat_number":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"},"contact":{"type":"string","description":"Name of the person to contact."},"driver_name":{"type":"string","description":"Carrier only. The driver named on the consignment note."},"driver_email":{"type":"string","format":"email"},"driver_phone":{"type":"string"}}},"Goods":{"type":"object","description":"One line of goods. ADR fields apply to dangerous goods.","properties":{"description":{"type":"string"},"quantity":{"type":"number"},"packaging":{"type":"string"},"weight_kg":{"type":"number"},"volume_m3":{"type":"number"},"marks_and_numbers":{"type":"string"},"statistical_number":{"type":"string"},"dangerous_goods":{"type":"boolean"},"adr_class":{"type":"string"},"un_number":{"type":"string"},"adr_shipping_name":{"type":"string"},"adr_packing_group":{"type":"string"},"adr_tunnel_code":{"type":"string"},"adr_notes":{"type":"string"}}},"Transport":{"type":"object","description":"The place of taking over the goods (CMR Box 4) and the place of\ndelivery (CMR Box 3). Each place needs at least a name or an address,\notherwise the document is rejected with `DOCUMENT_VALIDATION_FAILED`.\n","properties":{"vehicle_registration":{"type":"string"},"trailer_registration":{"type":"string"},"driver_name":{"type":"string"},"driver_phone":{"type":"string"},"driver_email":{"type":"string","format":"email"},"driver_license":{"type":"string"},"loading_place_name":{"type":"string","description":"Name of the place of taking over the goods (CMR Box 4)."},"loading_place_address":{"type":"string","description":"Address of the place of taking over the goods, at least 5 characters."},"loading_place_country":{"type":"string","description":"ISO 3166-1 alpha-2 country code, such as `PT`."},"loading_date":{"type":"string","format":"date"},"loading_started_at":{"type":"string","format":"date-time"},"loading_completed_at":{"type":"string","format":"date-time"},"delivery_place_name":{"type":"string","description":"Name of the place of delivery (CMR Box 3)."},"delivery_place_address":{"type":"string","description":"Address of the place of delivery, at least 5 characters."},"delivery_place_country":{"type":"string","description":"ISO 3166-1 alpha-2 country code, such as `ES`."},"delivery_date":{"type":"string","format":"date"},"delivery_started_at":{"type":"string","format":"date-time"},"delivery_completed_at":{"type":"string","format":"date-time"},"successive_carriers":{"type":"array","items":{"type":"string"}}}},"Instructions":{"type":"object","properties":{"payment_terms":{"type":"string"},"cash_on_delivery":{"type":"string"},"special_agreements":{"type":"string"},"observations":{"type":"string"},"documents_attached":{"type":"array","items":{"type":"string"}}}},"DocumentInput":{"type":"object","description":"The fields accepted when creating or updating a document. A CMR number\nis assigned by the platform and cannot be set.\n","properties":{"external_reference":{"type":"string","description":"Your own reference, for reconciling with your TMS."},"consignor":{"$ref":"#/components/schemas/Party"},"carrier":{"$ref":"#/components/schemas/Party"},"consignee":{"$ref":"#/components/schemas/Party"},"goods":{"type":"array","items":{"$ref":"#/components/schemas/Goods"}},"transport":{"$ref":"#/components/schemas/Transport"},"instructions":{"$ref":"#/components/schemas/Instructions"},"consignor_observations":{"type":"string"},"carrier_observations":{"type":"string"},"consignee_observations":{"type":"string"},"metadata":{"type":"object","description":"Free-form JSON object with your own keys. Stored as sent and\nreturned unchanged; the platform never interprets it.\n"},"timestamps":{"$ref":"#/components/schemas/TransportTimestamps"}}},"DocumentSummary":{"type":"object","properties":{"id":{"type":"integer"},"cmr_number":{"type":"string"},"external_reference":{"type":"string"},"status":{"$ref":"#/components/schemas/DocumentStatus"},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"Document":{"allOf":[{"$ref":"#/components/schemas/DocumentSummary"},{"type":"object","properties":{"consignor":{"$ref":"#/components/schemas/Party"},"carrier":{"$ref":"#/components/schemas/Party"},"consignee":{"$ref":"#/components/schemas/Party"},"goods":{"type":"array","items":{"$ref":"#/components/schemas/Goods"}},"transport":{"$ref":"#/components/schemas/Transport"},"instructions":{"$ref":"#/components/schemas/Instructions"},"consignor_observations":{"type":"string"},"carrier_observations":{"type":"string"},"consignee_observations":{"type":"string"},"signatures":{"type":"array","items":{"$ref":"#/components/schemas/SignatureSummary"}},"dates":{"$ref":"#/components/schemas/DocumentDates"},"timestamps":{"$ref":"#/components/schemas/TransportTimestamps"},"locations":{"$ref":"#/components/schemas/DocumentLocations"},"integrity":{"$ref":"#/components/schemas/SignatureIntegrity"},"versions_count":{"type":"integer"},"metadata":{"type":"object","description":"Free-form JSON object with your own keys, exactly as you sent it.\n"}}}]},"LifecycleStatus":{"type":"object","properties":{"cmr_number":{"type":"string"},"current_status":{"$ref":"#/components/schemas/DocumentStatus"},"next_required_signature":{"type":"string"},"can_complete":{"type":"boolean"},"dates":{"type":"object","properties":{"issued_at":{"type":"string","format":"date-time"},"accepted_at":{"type":"string","format":"date-time"},"delivered_at":{"type":"string","format":"date-time"},"completed_at":{"type":"string","format":"date-time"}}},"timestamps":{"$ref":"#/components/schemas/TransportTimestamps"}}},"DocumentCountsByStatus":{"type":"object","description":"Document counts grouped by status. A status with no documents is\nabsent rather than zero.\n","properties":{"draft":{"type":"integer"},"issued":{"type":"integer"},"accepted":{"type":"integer"},"delivered":{"type":"integer"},"completed":{"type":"integer"},"cancelled":{"type":"integer"}}},"TenantUsage":{"type":"object","properties":{"documents":{"type":"object","properties":{"total":{"type":"integer"},"by_status":{"$ref":"#/components/schemas/DocumentCountsByStatus"},"this_month":{"type":"integer"}}},"signatures":{"type":"object","properties":{"total":{"type":"integer"},"completed":{"type":"integer"},"pending":{"type":"integer"}}},"api_requests":{"type":"object","properties":{"rate_limit_per_minute":{"type":"integer"}}},"quota":{"type":"string","description":"The configured quota, or `unlimited` when the tenant has none."}}},"DocumentStatistics":{"type":"object","properties":{"total":{"type":"integer"},"by_status":{"$ref":"#/components/schemas/DocumentCountsByStatus"},"created_today":{"type":"integer"},"created_this_week":{"type":"integer"},"created_this_month":{"type":"integer"},"completed_this_month":{"type":"integer"}}},"ComplianceCheck":{"type":"object","properties":{"passed":{"type":"boolean"},"errors":{"type":"array","items":{"type":"string"}},"warnings":{"type":"array","items":{"type":"string"}}}},"ComplianceReport":{"type":"object","properties":{"status":{"type":"string","enum":["compliant","non_compliant"]},"checks":{"type":"object","properties":{"cmr_convention":{"$ref":"#/components/schemas/ComplianceCheck"},"eidas_requirements":{"$ref":"#/components/schemas/ComplianceCheck"},"data_completeness":{"$ref":"#/components/schemas/ComplianceCheck"}}},"verified_at":{"type":"string","format":"date-time"}}},"ResellerBilling":{"type":"object","properties":{"reseller_id":{"type":"string"},"billing_email":{"type":"string","format":"email"},"billing_settings":{"type":"object","description":"Free-form JSON object, whatever the reseller has stored."},"summary":{"type":"object","properties":{"max_tenants":{"type":"integer"},"active_tenants":{"type":"integer"},"total_tenants":{"type":"integer"},"total_documents":{"type":"integer"},"total_signatures":{"type":"integer"}}},"tenants":{"type":"array","items":{"type":"object","properties":{"tenant_id":{"type":"string"},"name":{"type":"string"},"reseller_reference":{"type":"string","nullable":true},"status":{"$ref":"#/components/schemas/AccountStatus"},"documents_count":{"type":"integer"},"signatures_count":{"type":"integer"}}}}}},"ResellerBillingUsage":{"type":"object","properties":{"period":{"type":"object","properties":{"start":{"type":"string","format":"date-time"},"end":{"type":"string","format":"date-time"}}},"summary":{"type":"object","properties":{"documents_created":{"type":"integer"},"documents_by_status":{"$ref":"#/components/schemas/DocumentCountsByStatus"},"signatures_created":{"type":"integer"},"signatures_completed":{"type":"integer"}}},"by_tenant":{"type":"array","items":{"type":"object","properties":{"tenant_id":{"type":"string"},"name":{"type":"string"},"reseller_reference":{"type":"string","nullable":true},"documents_created":{"type":"integer"},"signatures_created":{"type":"integer"},"signatures_completed":{"type":"integer"}}}}}},"DocumentDates":{"type":"object","description":"Lifecycle dates, set by the platform as the document advances.","properties":{"issued_at":{"type":"string","format":"date-time","nullable":true},"accepted_at":{"type":"string","format":"date-time","nullable":true},"delivered_at":{"type":"string","format":"date-time","nullable":true},"completed_at":{"type":"string","format":"date-time","nullable":true}}},"DocumentLocations":{"type":"object","description":"Where each lifecycle transition was recorded.","properties":{"issued":{"type":"string","nullable":true},"accepted":{"type":"string","nullable":true},"delivered":{"type":"string","nullable":true}}},"TransportTimestamps":{"type":"object","description":"Arrival and departure times for loading and delivery. Sent on update,\nreturned on every document.\n","properties":{"loading_started_at":{"type":"string","format":"date-time","nullable":true},"loading_completed_at":{"type":"string","format":"date-time","nullable":true},"delivery_started_at":{"type":"string","format":"date-time","nullable":true},"delivery_completed_at":{"type":"string","format":"date-time","nullable":true}}},"SignatureIntegrity":{"type":"object","description":"Whether each party has signed, and what changed since.","properties":{"consignor":{"$ref":"#/components/schemas/SignatureIntegrityEntry"},"carrier":{"$ref":"#/components/schemas/SignatureIntegrityEntry"},"consignee":{"$ref":"#/components/schemas/SignatureIntegrityEntry"}}},"SignatureIntegrityEntry":{"type":"object","properties":{"signed":{"type":"boolean"},"signed_at":{"type":"string","format":"date-time","nullable":true},"signed_by":{"type":"string","nullable":true},"hash":{"type":"string","nullable":true},"changes_after_signature":{"type":"array","description":"Fields changed after this party signed. Each entry also carries\n`signed_value` and `current_value`, left undeclared here because\nthey take the JSON type of the field that changed.\n","items":{"type":"object","properties":{"field":{"type":"string"}}}}}},"AuditEntry":{"type":"object","properties":{"event_type":{"type":"string"},"actor_type":{"type":"string"},"actor":{"type":"string"},"occurred_at":{"type":"string","format":"date-time"},"details":{"type":"object"}}},"SignatureRequest":{"type":"object","required":["signatory_role","signature_type"],"properties":{"signatory_role":{"$ref":"#/components/schemas/SignatoryRole"},"signature_type":{"$ref":"#/components/schemas/SignatureType"},"signatory_name":{"type":"string"},"contact":{"type":"string","description":"Email address or phone number in international format. Required for\n`remote`, which decides between email and SMS from the value.\n"},"locale":{"$ref":"#/components/schemas/Locale"}}},"SignPayload":{"type":"object","properties":{"signature_data":{"type":"string","description":"The drawn signature as a data URI (PNG)."},"certificate":{"type":"string","description":"A PEM certificate, when signing with one instead."},"signer_info":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"},"phone":{"type":"string"}}},"location":{"type":"string"}}},"Geolocation":{"type":"object","description":"Where the signature was taken, as reported by the signing device.","properties":{"latitude":{"type":"number"},"longitude":{"type":"number"},"accuracy":{"type":"number"}}},"SignatureSummary":{"type":"object","description":"A signature as it appears inside a document. The signature endpoints\nanswer with the fuller `Signature` instead.\n","properties":{"id":{"type":"integer"},"role":{"$ref":"#/components/schemas/SignatoryRole"},"type":{"$ref":"#/components/schemas/SignatureType"},"status":{"$ref":"#/components/schemas/SignatureStatus"},"signatory_name":{"type":"string","nullable":true},"signatory_email":{"type":"string","format":"email","nullable":true},"signatory_phone":{"type":"string","nullable":true},"signed_at":{"type":"string","format":"date-time","nullable":true},"timestamp_time":{"type":"string","format":"date-time","nullable":true},"geolocation":{"$ref":"#/components/schemas/Geolocation"}}},"Signature":{"type":"object","properties":{"id":{"type":"integer"},"document_cmr":{"type":"string"},"signature_type":{"$ref":"#/components/schemas/SignatureType"},"signatory_role":{"$ref":"#/components/schemas/SignatoryRole"},"signatory_name":{"type":"string","nullable":true},"signatory_email":{"type":"string","format":"email","nullable":true},"signatory_phone":{"type":"string","nullable":true},"status":{"$ref":"#/components/schemas/SignatureStatus"},"signed_at":{"type":"string","format":"date-time","nullable":true},"has_biometric_data":{"type":"boolean"},"has_certificate":{"type":"boolean"},"metadata":{"type":"object","description":"Free-form JSON object kept with the signature."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"RequestedSignature":{"allOf":[{"$ref":"#/components/schemas/Signature"},{"type":"object","properties":{"share_token":{"type":"string","description":"Present for remote signatures; addresses the signing page."},"share_expires_at":{"type":"string","format":"date-time"}}}]},"ShareInput":{"type":"object","properties":{"share_type":{"type":"string"},"permissions":{"$ref":"#/components/schemas/SharePermission"},"recipient_email":{"type":"string","format":"email","description":"When given, the link is emailed to this address."},"expires_at":{"type":"string","format":"date-time"}}},"Share":{"type":"object","properties":{"token":{"type":"string"},"type":{"$ref":"#/components/schemas/SharePermission"},"url":{"type":"string","format":"uri"},"recipient_email":{"type":"string","format":"email"},"expires_at":{"type":"string","format":"date-time"},"revoked_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}},"WebhookConfig":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["issued","accepted","delivered","completed","cancelled"]}},"secret":{"type":"string","description":"Used to compute the `X-Webhook-Signature` header, an HMAC-SHA256\nhex digest of the raw request body. Returned only when set.\n"},"active":{"type":"boolean"}}},"WebhookUpdate":{"type":"object","properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}}}},"SignupRequest":{"type":"object","required":["email","company_name","vat_number","address","company_type"],"properties":{"email":{"type":"string","format":"email"},"company_name":{"type":"string"},"vat_number":{"type":"string","description":"Validated against the national register where available.","example":"PT123456789"},"address":{"type":"string"},"company_type":{"$ref":"#/components/schemas/CompanyType"},"country_code":{"type":"string","description":"ISO 3166-1 alpha-2."}}},"SignupResult":{"type":"object","properties":{"tenant_id":{"type":"string"},"email":{"type":"string","format":"email"},"company_name":{"type":"string"},"status":{"$ref":"#/components/schemas/AccountStatus"},"message":{"type":"string"},"expires_in":{"type":"string"}}},"VerifiedTenant":{"type":"object","properties":{"tenant_id":{"type":"string"},"company_name":{"type":"string"},"email":{"type":"string","format":"email"},"api_key":{"type":"string","description":"Shown only here. Store it; it cannot be read back."},"status":{"$ref":"#/components/schemas/AccountStatus"},"rate_limit_per_minute":{"type":"integer"},"message":{"type":"string"}}},"Tenant":{"type":"object","properties":{"tenant_id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"vat_number":{"type":"string"},"address":{"type":"string"},"country_code":{"type":"string"},"company_type":{"$ref":"#/components/schemas/CompanyType"},"default_locale":{"$ref":"#/components/schemas/Locale"},"status":{"$ref":"#/components/schemas/AccountStatus"},"rate_limit_per_minute":{"type":"integer"},"created_at":{"type":"string","format":"date-time"}}},"TenantWithKey":{"allOf":[{"$ref":"#/components/schemas/Tenant"},{"type":"object","properties":{"api_key":{"type":"string","description":"Shown only here. Store it; it cannot be read back."}}}]},"TenantUpdate":{"type":"object","properties":{"name":{"type":"string"},"company_type":{"$ref":"#/components/schemas/CompanyType"},"address":{"type":"string"},"country_code":{"type":"string"},"metadata":{"type":"object"}}},"ResellerSignupRequest":{"type":"object","required":["email","company_name","vat_number","address"],"properties":{"email":{"type":"string","format":"email"},"company_name":{"type":"string"},"vat_number":{"type":"string","example":"PT999888777"},"address":{"type":"string"},"country_code":{"type":"string"},"max_tenants":{"type":"integer","default":100,"description":"How many sub-tenants this reseller may create."},"rate_limit_per_minute":{"type":"integer","default":300}}},"ResellerSignupResult":{"type":"object","properties":{"reseller_id":{"type":"string"},"email":{"type":"string","format":"email"},"company_name":{"type":"string"},"address":{"type":"string"},"country_code":{"type":"string"},"status":{"$ref":"#/components/schemas/AccountStatus"},"max_tenants":{"type":"integer"},"message":{"type":"string"},"expires_in":{"type":"string"}}},"VerifiedReseller":{"type":"object","properties":{"reseller_id":{"type":"string"},"company_name":{"type":"string"},"email":{"type":"string","format":"email"},"master_api_key":{"type":"string","description":"Shown only here. Afterwards the profile returns it masked."},"max_tenants":{"type":"integer"},"status":{"$ref":"#/components/schemas/AccountStatus"},"rate_limit_per_minute":{"type":"integer"},"message":{"type":"string"}}},"Reseller":{"type":"object","properties":{"reseller_id":{"type":"string"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"vat_number":{"type":"string"},"address":{"type":"string"},"country_code":{"type":"string"},"status":{"$ref":"#/components/schemas/AccountStatus"},"master_api_key":{"type":"string","description":"Masked, showing only the prefix and the last characters."},"max_tenants":{"type":"integer"},"tenants_count":{"type":"integer"},"remaining_tenant_slots":{"type":"integer"},"rate_limit_per_minute":{"type":"integer"}}},"ResellerUpdate":{"type":"object","properties":{"name":{"type":"string"},"address":{"type":"string"},"country_code":{"type":"string"},"metadata":{"type":"object"}}},"ResellerTenantInput":{"type":"object","required":["company_name","vat_number","company_type","address"],"properties":{"company_name":{"type":"string"},"vat_number":{"type":"string"},"company_type":{"$ref":"#/components/schemas/CompanyType"},"address":{"type":"string"},"email":{"type":"string","format":"email","description":"Optional; a managed tenant may have no email of its own."},"country_code":{"type":"string"},"default_locale":{"$ref":"#/components/schemas/Locale"},"rate_limit_per_minute":{"type":"integer"},"metadata":{"type":"object"}}},"ResellerTenantUpdate":{"type":"object","properties":{"company_name":{"type":"string"},"company_type":{"$ref":"#/components/schemas/CompanyType"},"address":{"type":"string"},"country_code":{"type":"string"},"default_locale":{"$ref":"#/components/schemas/Locale"},"rate_limit_per_minute":{"type":"integer"},"metadata":{"type":"object"}}}}}}