{"openapi":"3.1.0","info":{"title":"codus-nullus-voice/portal-api","version":"0.0.0","description":"Customer + admin HTTP surface for the Codus Nullus wholesale voice platform. Hono on Cloudflare Workers. See plan 0006.","contact":{"name":"Codus Nullus","url":"https://c0.lt"}},"servers":[{"url":"https://api.c0.lt/v1","description":"Production"},{"url":"https://staging-api.c0.lt/v1","description":"Staging"},{"url":"http://localhost:8787/v1","description":"Local (wrangler dev)"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT bearer. Claims: sub (user id), acc (account id), roles[] (customer | admin | support)."},"bearerAuthAdmin":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Same JWT scheme as bearerAuth; additionally requires the admin role claim."}},"schemas":{"Problem":{"type":"object","properties":{"type":{"type":"string","format":"uri","description":"Stable error code as a URN. Clients localize on this value.","example":"urn:codus-nullus:voice:problem:balance.insufficient"},"title":{"type":"string","description":"English fallback for raw HTTP clients. Never localized.","example":"Insufficient prepaid balance"},"status":{"type":"integer","example":402},"detail":{"type":"string","description":"English diagnostic. Not localized.","example":"Top-up of at least EUR 10 is required."},"instance":{"type":"string","description":"Path that produced the error.","example":"/v1/payments/topups"},"invalid_params":{"type":"array","items":{"type":"object","properties":{"name":{"type":"string"},"reason":{"type":"string"}},"required":["name","reason"]},"description":"Populated for 422 validation errors."},"retry_after":{"type":"integer","description":"Seconds to wait before retry; populated on 429."}},"required":["type","title","status"]},"SessionUser":{"type":"object","properties":{"id":{"type":"string","example":"usr_01HX9Q2K8B3R4T5V6W7X8Y9Z0A"},"email":{"type":"string","format":"email"},"account_id":{"type":"string","example":"acc_01HX9Q2K8B3R4T5V6W7X8Y9Z0A"},"roles":{"type":"array","items":{"type":"string","enum":["customer","admin","support"]}}},"required":["id","email","account_id","roles"]},"SessionResponse":{"type":"object","properties":{"access_token":{"type":"string","description":"Short-lived JWT bearer (1h).","example":"eyJhbGciOi..."},"refresh_token":{"type":"string","description":"Opaque 30-day refresh token; rotates on use.","example":"rtk_..."},"expires_at":{"type":"integer","description":"Access-token expiry as unix epoch seconds.","example":1747300000},"token_type":{"type":"string","enum":["Bearer"]},"user":{"$ref":"#/components/schemas/SessionUser"}},"required":["access_token","refresh_token","expires_at","token_type","user"]},"SignInTwoFaRequired":{"type":"object","properties":{"status":{"type":"string","enum":["2fa_required"]},"tmp_token":{"type":"string","description":"Short-lived JWT to present to /v1/admin/2fa/verify."}},"required":["status","tmp_token"]},"SignInResponse":{"anyOf":[{"$ref":"#/components/schemas/SessionResponse"},{"$ref":"#/components/schemas/SignInTwoFaRequired"}]},"SignInRequest":{"type":"object","properties":{"email":{"type":"string","format":"email","example":"ops@example.com"},"password":{"type":"string","minLength":8,"example":"supersecret"}},"required":["email","password"]},"RefreshRequest":{"type":"object","properties":{"refresh_token":{"type":"string"}},"required":["refresh_token"]},"SignOutRequest":{"type":"object","properties":{"refresh_token":{"type":"string"}},"required":["refresh_token"]},"ForgotPasswordRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"ResetPasswordRequest":{"type":"object","properties":{"token":{"type":"string"},"new_password":{"type":"string","minLength":8}},"required":["token","new_password"]},"FirstLoginRequest":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]},"BetaSignupResponse":{"type":"object","properties":{"message":{"type":"string","description":"Anti-enumerating envelope; identical whether the email was fresh or replayed.","example":"Check your inbox"}},"required":["message"]},"BetaSignupRequest":{"type":"object","properties":{"legal_name":{"type":"string","minLength":1,"maxLength":200,"description":"Registered legal name of the prospective customer.","example":"Acme Telecom Ltd"},"trading_name":{"type":"string","maxLength":200,"description":"Optional public-facing brand name if different from the legal name.","example":"Acme"},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"Country of incorporation (ISO 3166-1 alpha-2).","example":"LT"},"contact_name":{"type":"string","minLength":1,"maxLength":100,"description":"Primary contact for the signup.","example":"Jane Doe"},"contact_email":{"type":"string","format":"email","description":"Login + notification email. UNIQUE across accounts.","example":"jane@acme.example"},"contact_phone":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$","description":"Optional E.164 phone number.","example":"+37061234567"},"password":{"type":"string","minLength":12,"description":"Initial portal password. Minimum 12 characters; argon2id-equivalent hash stored server-side."}},"required":["legal_name","country","contact_name","contact_email","password"]},"Address":{"type":"object","nullable":true,"properties":{"line1":{"type":"string"},"line2":{"type":"string"},"city":{"type":"string"},"postal_code":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"}},"required":["line1","city","postal_code","country"]},"OnboardingStatus":{"type":"string","enum":["signup_pending","docs_requested","under_review","approved","suspended"]},"Account":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"company_name":{"type":"string","example":"Acme Telecom UAB"},"locale":{"type":"string","pattern":"^[a-z]{2}(-[A-Z]{2})?$","description":"BCP 47 locale tag (subset).","example":"en"},"postal_address":{"$ref":"#/components/schemas/Address"},"invoice_address":{"$ref":"#/components/schemas/Address"},"vat_id":{"type":"string","nullable":true,"example":"LT100017026817"},"vat_status":{"type":"string","enum":["not_verified","pending","exempt","valid","invalid"]},"onboarding_status":{"$ref":"#/components/schemas/OnboardingStatus"},"account_manager":{"type":"object","nullable":true,"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"name":{"type":"string"},"email":{"type":"string","format":"email"}},"required":["id","name","email"]},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","company_name","locale","postal_address","invoice_address","vat_id","vat_status","onboarding_status","account_manager","created_at","updated_at"]},"AccountUpdate":{"type":"object","properties":{"company_name":{"type":"string"},"locale":{"type":"string","pattern":"^[a-z]{2}(-[A-Z]{2})?$","description":"BCP 47 locale tag (subset).","example":"en"},"postal_address":{"$ref":"#/components/schemas/Address"},"invoice_address":{"$ref":"#/components/schemas/Address"},"vat_id":{"type":"string"}}},"Money":{"type":"object","properties":{"amount_minor":{"type":"integer","description":"Amount in minor units (e.g. cents). Negative values allowed in ledger contexts.","example":1250},"currency":{"type":"string","minLength":3,"maxLength":3,"pattern":"^[A-Z]{3}$","description":"ISO 4217 currency code","example":"EUR"}},"required":["amount_minor","currency"]},"Balance":{"type":"object","properties":{"current":{"$ref":"#/components/schemas/Money"},"minimum":{"$ref":"#/components/schemas/Money"},"soft_warn_threshold":{"$ref":"#/components/schemas/Money"},"last_debit_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["current","minimum","soft_warn_threshold","last_debit_at"]},"Quota":{"type":"object","properties":{"zone":{"type":"string","example":"EU"},"in_use":{"type":"integer"},"limit":{"type":"integer"},"peak_today":{"type":"integer"}},"required":["zone","in_use","limit","peak_today"]},"QuotaList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Quota"}}},"required":["data"]},"AsrAcd":{"type":"object","properties":{"period":{"type":"string","enum":["24h","7d","30d"]},"asr":{"type":"number","minimum":0,"maximum":1,"description":"Answer-Seizure Ratio (0-1).","example":0.62},"acd_seconds":{"type":"integer","description":"Average Call Duration in seconds.","example":184},"sample_size":{"type":"integer"}},"required":["period","asr","acd_seconds","sample_size"]},"AccountStatus":{"type":"string","enum":["beta_signup","beta_card_pending","beta_waitlist","beta_approved","beta_declined","live"]},"MyAccountResponse":{"type":"object","properties":{"id":{"type":"string","example":"acc_0e8b4a262b8f4f7f9b343a4a8f3a3a11"},"legal_name":{"type":"string","example":"Acme Telecom Ltd"},"trading_name":{"type":"string","nullable":true,"example":"Acme"},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"vat_id":{"type":"string","nullable":true,"example":"LT100017026817"},"contact_name":{"type":"string","example":"Jane Doe"},"contact_email":{"type":"string","format":"email","example":"jane@acme.example"},"contact_phone":{"type":"string","nullable":true,"pattern":"^\\+[1-9]\\d{6,14}$","description":"E.164 phone number with leading +.","example":"+37061234567"},"status":{"$ref":"#/components/schemas/AccountStatus"},"waitlist_position":{"type":"integer","nullable":true,"description":"Null until the account enters beta_waitlist.","example":3},"waitlist_joined_at":{"type":"integer","nullable":true,"description":"Unix seconds when the account joined the waitlist; null prior.","example":1715000000},"created_at":{"type":"integer","description":"Unix seconds.","example":1714900000}},"required":["id","legal_name","country","contact_name","contact_email","status","created_at"]},"MyWaitlistResponse":{"type":"object","properties":{"position":{"type":"integer","nullable":true,"description":"Position in the queue; null when the account is not yet on the waitlist.","example":3},"total":{"type":"integer","description":"Total number of accounts currently in beta_waitlist.","example":27},"status":{"$ref":"#/components/schemas/AccountStatus"}},"required":["position","total","status"]},"TrafficType":{"type":"string","enum":["retail","call_center","ai_voice","iot","fax","other"]},"TrafficProfileResponse":{"type":"object","properties":{"estimated_minutes_per_month":{"type":"integer","minimum":0},"target_countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"}},"traffic_types":{"type":"array","items":{"$ref":"#/components/schemas/TrafficType"}},"notes":{"type":"string","nullable":true},"created_at":{"type":"integer","description":"Unix seconds."},"updated_at":{"type":"integer","description":"Unix seconds."}},"required":["estimated_minutes_per_month","target_countries","traffic_types","created_at","updated_at"]},"TrafficProfileRequest":{"type":"object","properties":{"estimated_minutes_per_month":{"type":"integer","minimum":0,"description":"Expected monthly billable minutes across all target countries.","example":50000},"target_countries":{"type":"array","items":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"description":"Destinations the customer plans to terminate to.","example":["LT","LV","EE"]},"traffic_types":{"type":"array","items":{"$ref":"#/components/schemas/TrafficType"},"description":"Use cases driving the volume.","example":["retail","call_center"]},"notes":{"type":"string","maxLength":2000,"description":"Optional free-text context for the ops reviewer."}},"required":["estimated_minutes_per_month","target_countries","traffic_types"]},"ComplianceIntakeStatus":{"type":"string","enum":["open","submitted","approved","rejected"]},"ComplianceIntake":{"type":"object","properties":{"id":{"type":"string","example":"kyb_8a1c9b8a4f1a4d2c8e3d9b2a4f1a4d2c"},"status":{"$ref":"#/components/schemas/ComplianceIntakeStatus"},"required_docs":{"type":"array","items":{"type":"string"},"description":"Canonical doc-kind keys the customer must upload before submitting.","example":["articles_of_incorporation","vat_certificate","ubo_declaration","director_id","proof_of_address","source_of_traffic_declaration"]},"uploaded_docs":{"type":"array","items":{"type":"string"},"description":"Subset of required_docs that the customer has already uploaded at least one file for.","example":["articles_of_incorporation"]},"reviewer_note":{"type":"string","description":"Note from the admin reviewer; populated on approve / reject."},"submitted_at":{"type":"integer","description":"Unix epoch seconds. Populated when status flips from open to submitted."},"reviewed_at":{"type":"integer","description":"Unix epoch seconds. Populated when an admin approves or rejects."},"created_at":{"type":"integer","description":"Unix epoch seconds."},"updated_at":{"type":"integer","description":"Unix epoch seconds."}},"required":["id","status","required_docs","uploaded_docs","created_at","updated_at"]},"KybUploadResponse":{"type":"object","properties":{"id":{"type":"string","example":"kybd_8a1c9b8a4f1a4d2c8e3d9b2a4f1a4d2c"},"doc_kind":{"type":"string","example":"articles_of_incorporation"},"content_type":{"type":"string","example":"application/pdf"},"size_bytes":{"type":"integer","example":123456},"uploaded_at":{"type":"integer","description":"Unix epoch seconds."}},"required":["id","doc_kind","content_type","size_bytes","uploaded_at"]},"PaymentMethod":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"brand":{"type":"string","enum":["visa","mastercard","amex","other"]},"last4":{"type":"string","minLength":4,"maxLength":4},"exp_month":{"type":"integer","minimum":1,"maximum":12},"exp_year":{"type":"integer"},"is_default":{"type":"boolean"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","brand","last4","exp_month","exp_year","is_default","created_at"]},"PaymentMethodCreateResponse":{"type":"object","properties":{"checkout_url":{"type":"string","format":"uri"},"order_id":{"type":"string","description":"Revolut order id used to verify the saved method."}},"required":["checkout_url","order_id"]},"PaymentMethodCreateRequest":{"type":"object","properties":{"return_url":{"type":"string","format":"uri","description":"URL the customer is redirected to after Revolut hosted checkout."}},"required":["return_url"]},"TopupLiveResponse":{"type":"object","properties":{"topup_id":{"type":"string","description":"Revolut order id."},"checkout_url":{"type":"string","format":"uri"},"amount_minor":{"type":"integer"},"currency":{"type":"string","enum":["EUR"]},"status":{"type":"string","enum":["pending"]}},"required":["topup_id","checkout_url","amount_minor","currency","status"]},"TopupLiveRequest":{"type":"object","properties":{"amount_minor":{"type":"integer","minimum":100,"description":"Amount in minor units (cents). Minimum 100 (1.00 EUR) for the live test.","example":100},"currency":{"type":"string","enum":["EUR"],"example":"EUR"}},"required":["amount_minor","currency"]},"Topup":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"amount_minor":{"type":"integer","description":"Amount in minor units (cents).","example":1000},"currency":{"type":"string","minLength":3,"maxLength":3,"pattern":"^[A-Z]{3}$","example":"EUR"},"status":{"type":"string","enum":["pending","completed","failed","expired"]},"balance_after_minor":{"type":"integer","nullable":true,"description":"Prepaid balance after this topup posted. NULL until the ledger lands."},"initiated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"completed_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","amount_minor","currency","status","balance_after_minor","initiated_at","completed_at"]},"PageMeta":{"type":"object","properties":{"next_cursor":{"type":"string","nullable":true,"description":"Opaque cursor. Null when no further pages exist.","example":"eyJ0IjoiMjAyNi0wNS0xNFQwOTozMDowMFoiLCJpIjoiYWFhIn0"},"limit":{"type":"integer","example":50}},"required":["next_cursor","limit"]},"TopupPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Topup"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"AutoRecharge":{"type":"object","properties":{"enabled":{"type":"boolean"},"threshold":{"$ref":"#/components/schemas/Money"},"recharge_amount":{"$ref":"#/components/schemas/Money"},"payment_method_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"}},"required":["enabled","threshold","recharge_amount","payment_method_id"]},"LowBalanceNotify":{"type":"object","properties":{"enabled":{"type":"boolean"},"threshold_pct":{"type":"integer","minimum":1,"maximum":100,"description":"Trigger when balance falls under this fraction of trailing-30d spend.","example":30}},"required":["enabled","threshold_pct"]},"Invoice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"number":{"type":"string","example":"VOICE-2026-000142"},"status":{"type":"string","enum":["draft","issued","paid","void","credited"]},"issue_date":{"type":"string","format":"date","example":"2026-05-14"},"supply_date":{"type":"string","format":"date"},"due_date":{"type":"string","format":"date"},"subtotal":{"$ref":"#/components/schemas/Money"},"vat":{"$ref":"#/components/schemas/Money"},"total":{"$ref":"#/components/schemas/Money"},"paid_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"pdf_url":{"type":"string","nullable":true,"format":"uri","description":"Signed R2 URL. Refresh by hitting GET /invoices/{id}/pdf if expired."}},"required":["id","number","status","issue_date","supply_date","due_date","subtotal","vat","total","paid_at","pdf_url"]},"InvoicePage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"VatStatus":{"type":"object","properties":{"status":{"type":"string","enum":["not_verified","pending","exempt","valid","invalid"]},"vat_id":{"type":"string","nullable":true},"last_checked_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"proof_documents":{"type":"array","items":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"}}},"required":["status","vat_id","last_checked_at","proof_documents"]},"Trunk":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"name":{"type":"string"},"zone":{"type":"string","example":"EU"},"channel_cap":{"type":"integer","minimum":1},"is_default":{"type":"boolean"},"sip_endpoint_hint":{"type":"string","nullable":true,"example":"sip:trunk1@sip.c0.lt:5060"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","name","zone","channel_cap","is_default","sip_endpoint_hint","created_at"]},"TrunkPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Trunk"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"TrunkCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1},"zone":{"type":"string"},"channel_cap":{"type":"integer","minimum":1},"is_default":{"type":"boolean","default":false}},"required":["name","zone","channel_cap"]},"TrunkUpdate":{"type":"object","properties":{"name":{"type":"string","minLength":1},"zone":{"type":"string"},"channel_cap":{"type":"integer","minimum":1},"is_default":{"type":"boolean"}}},"NumberType":{"type":"string","enum":["local","tollfree","mobile"]},"NumberCapability":{"type":"string","enum":["voice","sms","fax"]},"Did":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"e164":{"type":"string","pattern":"^\\+[1-9]\\d{6,14}$","description":"E.164 phone number with leading +.","example":"+37061234567"},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"type":{"$ref":"#/components/schemas/NumberType"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/NumberCapability"}},"trunk_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"monthly":{"$ref":"#/components/schemas/Money"},"next_renewal_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"regulatory":{"type":"string","enum":["api","docs_required"]}},"required":["id","e164","country","type","capabilities","trunk_id","monthly","next_renewal_at","regulatory"]},"TrunkDidPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Did"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"IpAllowEntry":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"cidr":{"type":"string","example":"203.0.113.0/24"},"note":{"type":"string"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","cidr","created_at"]},"IpAllowCreate":{"type":"object","properties":{"cidr":{"type":"string","example":"203.0.113.0/24"},"note":{"type":"string"}},"required":["cidr"]},"FraudCaps":{"type":"object","properties":{"max_spend_per_day":{"$ref":"#/components/schemas/Money"},"max_rate_per_minute":{"$ref":"#/components/schemas/Money"}},"required":["max_spend_per_day","max_rate_per_minute"]},"InventoryItem":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"type":{"$ref":"#/components/schemas/NumberType"},"area_name":{"type":"string","nullable":true,"example":"Vilnius"},"prefix":{"type":"string","example":"+3705"},"capabilities":{"type":"array","items":{"$ref":"#/components/schemas/NumberCapability"}},"monthly":{"$ref":"#/components/schemas/Money"},"setup":{"$ref":"#/components/schemas/Money"},"regulatory":{"type":"string","enum":["api","docs_required"],"description":"api = self-serve; docs_required triggers a compliance intake."},"required_documents":{"type":"array","items":{"type":"string"}}},"required":["id","country","type","area_name","prefix","capabilities","monthly","setup","regulatory"]},"InventoryPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/InventoryItem"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"NumberOrder":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"inventory_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["pending_documents","provisioning","active","failed","cancelled"]},"did":{"type":"string","nullable":true,"pattern":"^\\+[1-9]\\d{6,14}$","description":"E.164 phone number with leading +.","example":"+37061234567"},"compliance_intake_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"failure_reason":{"type":"string","nullable":true},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","inventory_id","status","did","compliance_intake_id","failure_reason","created_at"]},"NumberOrderCreate":{"type":"object","properties":{"inventory_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"trunk_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"}},"required":["inventory_id","trunk_id"]},"NumberOrderPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/NumberOrder"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"DidPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Did"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"DidUpdate":{"type":"object","properties":{"trunk_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"}},"required":["trunk_id"]},"IntakePage":{"type":"object","properties":{"data":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"Cdr":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"call_id":{"type":"string"},"leg":{"type":"string","enum":["origination","termination"]},"started_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"answered_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"ended_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"duration_seconds":{"type":"integer"},"calling":{"type":"string"},"called":{"type":"string"},"country":{"type":"string","nullable":true,"minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"destination_name":{"type":"string","nullable":true},"status":{"type":"string","enum":["answered","no_answer","busy","failed","cancelled"]},"customer_charge":{"$ref":"#/components/schemas/Money"},"trunk_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"}},"required":["id","call_id","leg","started_at","answered_at","ended_at","duration_seconds","calling","called","country","destination_name","status","customer_charge","trunk_id"]},"CdrPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Cdr"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"CdrSummaryRow":{"type":"object","properties":{"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"destination_name":{"type":"string"},"attempts":{"type":"integer"},"answered":{"type":"integer"},"minutes":{"type":"number"},"charge":{"$ref":"#/components/schemas/Money"}},"required":["country","destination_name","attempts","answered","minutes","charge"]},"CdrSummary":{"type":"object","properties":{"date":{"type":"string","format":"date"},"rows":{"type":"array","items":{"$ref":"#/components/schemas/CdrSummaryRow"}},"totals":{"type":"object","properties":{"attempts":{"type":"integer"},"answered":{"type":"integer"},"minutes":{"type":"number"},"charge":{"$ref":"#/components/schemas/Money"}},"required":["attempts","answered","minutes","charge"]}},"required":["date","rows","totals"]},"CdrExport":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["queued","running","ready","failed","expired"]},"format":{"type":"string","enum":["csv","jsonl"]},"download_url":{"type":"string","nullable":true,"format":"uri"},"requested_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"completed_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","format","download_url","requested_at","completed_at"]},"CdrExportCreate":{"type":"object","properties":{"from":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"to":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"format":{"type":"string","enum":["csv","jsonl"],"default":"csv"}},"required":["from","to"]},"CapacityPoint":{"type":"object","properties":{"bucket_start":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"peak_concurrent":{"type":"integer"}},"required":["bucket_start","peak_concurrent"]},"Capacity":{"type":"object","properties":{"period":{"type":"string","enum":["week","month"]},"points":{"type":"array","items":{"$ref":"#/components/schemas/CapacityPoint"}}},"required":["period","points"]},"Rate":{"type":"object","properties":{"prefix":{"type":"string","example":"+3706"},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"destination_name":{"type":"string","example":"Lithuania - Mobile"},"rate_per_minute":{"$ref":"#/components/schemas/Money"},"billing_increment_seconds":{"type":"integer","example":60},"minimum_seconds":{"type":"integer","example":30},"effective_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["prefix","country","destination_name","rate_per_minute","billing_increment_seconds","minimum_seconds","effective_at"]},"RatePage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Rate"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"RateDiffEntry":{"type":"object","properties":{"prefix":{"type":"string"},"destination_name":{"type":"string"},"change":{"type":"string","enum":["added","removed","increased","decreased"]},"from":{"allOf":[{"$ref":"#/components/schemas/Money"},{"nullable":true}]},"to":{"allOf":[{"$ref":"#/components/schemas/Money"},{"nullable":true}]}},"required":["prefix","destination_name","change","from","to"]},"TicketMessage":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"body":{"type":"string"},"author_kind":{"type":"string","enum":["customer","team"]},"author_name":{"type":"string"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","body","author_kind","author_name","created_at"]},"Ticket":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"subject":{"type":"string"},"status":{"type":"string","enum":["open","pending_customer","pending_team","resolved","closed"]},"priority":{"type":"string","enum":["low","normal","high"],"default":"normal"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"messages":{"type":"array","items":{"$ref":"#/components/schemas/TicketMessage"}}},"required":["id","subject","status","created_at","updated_at"]},"TicketPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Ticket"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"TicketCreate":{"type":"object","properties":{"subject":{"type":"string","minLength":1},"body":{"type":"string","minLength":1},"priority":{"type":"string","enum":["low","normal","high"],"default":"normal"}},"required":["subject","body"]},"TicketMessageCreate":{"type":"object","properties":{"body":{"type":"string","minLength":1}},"required":["body"]},"Notice":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"severity":{"type":"string","enum":["info","warning","critical"]},"title":{"type":"string"},"body":{"type":"string"},"starts_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"ends_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","severity","title","body","starts_at","ends_at"]},"Notification":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"code":{"type":"string","description":"Stable code; UI looks up the message in its dictionary (per plan 0013).","example":"balance.low"},"severity":{"type":"string","enum":["info","warning","critical"]},"payload":{"type":"object","additionalProperties":{"nullable":true},"description":"Code-specific data; UI templates use it for substitutions."},"read_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","code","severity","payload","read_at","created_at"]},"NotificationPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"RevolutWebhookAck":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]},"CardSetupResponse":{"type":"object","properties":{"checkout_url":{"type":"string","format":"uri","description":"Revolut hosted checkout URL. Redirect the customer here to enter card details."},"payment_method_id":{"type":"string","description":"Local payment_methods.id (pmv_<uuid>) for the in-flight verification.","example":"pmv_8a1d3f7b4c5e6a7d8b9c0d1e2f3a4b5c"}},"required":["checkout_url","payment_method_id"]},"CardSetupRequest":{"type":"object","properties":{}},"MyPaymentMethodResponse":{"type":"object","properties":{"id":{"type":"string","example":"pmv_8a1d..."},"status":{"type":"string","enum":["pending_verification","completing","verified","verification_failed"],"description":"Verification lifecycle status."},"brand":{"type":"string","nullable":true,"example":"visa"},"last4":{"type":"string","nullable":true,"example":"4242"},"exp_month":{"type":"integer","nullable":true,"example":12},"exp_year":{"type":"integer","nullable":true,"example":2030}},"required":["id","status"]},"AdminCustomer":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"company_name":{"type":"string"},"contact_email":{"type":"string","format":"email"},"onboarding_status":{"$ref":"#/components/schemas/OnboardingStatus"},"account_manager_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"monthly_spend_30d":{"$ref":"#/components/schemas/Money"},"balance":{"$ref":"#/components/schemas/Money"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","company_name","contact_email","onboarding_status","account_manager_id","monthly_spend_30d","balance","created_at"]},"AdminCustomerPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminCustomer"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"AdminCustomerUpdate":{"type":"object","properties":{"onboarding_status":{"$ref":"#/components/schemas/OnboardingStatus"},"account_manager_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"}}},"AdminImpersonateResponse":{"type":"object","properties":{"access_token":{"type":"string"},"expires_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"scope":{"type":"string","enum":["read_only"]}},"required":["access_token","expires_at","scope"]},"AdminNote":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"body":{"type":"string"},"author_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"author_name":{"type":"string"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","body","author_id","author_name","created_at"]},"AdminNotePage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminNote"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"AdminNoteCreate":{"type":"object","properties":{"body":{"type":"string","minLength":1}},"required":["body"]},"AdminOnboardingPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminCustomer"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"Upstream":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"name":{"type":"string","example":"Voxbeam"},"status":{"type":"string","enum":["active","disabled"]},"dispatcher_group_id":{"type":"integer"},"base_currency":{"type":"string","minLength":3,"maxLength":3},"markup_percent":{"type":"number","example":12.5},"rate_import_url":{"type":"string","nullable":true,"format":"uri"},"rate_import_schedule":{"type":"string","nullable":true,"description":"Cron expression.","example":"0 5 * * *"},"last_import_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"health":{"type":"string","enum":["unknown","up","degraded","down"]}},"required":["id","name","status","dispatcher_group_id","base_currency","markup_percent","rate_import_url","rate_import_schedule","last_import_at","health"]},"UpstreamCreate":{"type":"object","properties":{"name":{"type":"string","minLength":1},"dispatcher_group_id":{"type":"integer"},"base_currency":{"type":"string","minLength":3,"maxLength":3},"markup_percent":{"type":"number"},"rate_import_url":{"type":"string","format":"uri"},"rate_import_schedule":{"type":"string"}},"required":["name","dispatcher_group_id","base_currency","markup_percent"]},"UpstreamUpdate":{"type":"object","properties":{"status":{"type":"string","enum":["active","disabled"]},"markup_percent":{"type":"number"},"rate_import_url":{"type":"string","format":"uri"},"rate_import_schedule":{"type":"string"}}},"AdminRate":{"type":"object","properties":{"upstream_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"prefix":{"type":"string"},"destination_name":{"type":"string"},"base":{"$ref":"#/components/schemas/Money"},"effective_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["upstream_id","prefix","destination_name","base","effective_at"]},"AdminRatePage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminRate"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"DidInventoryRow":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"upstream_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"e164":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"type":{"type":"string","enum":["local","tollfree","mobile"]},"monthly":{"$ref":"#/components/schemas/Money"},"is_active":{"type":"boolean"},"regulatory_override":{"type":"string","nullable":true,"enum":["api","docs_required"]}},"required":["id","upstream_id","e164","country","type","monthly","is_active","regulatory_override"]},"DidInventoryPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/DidInventoryRow"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"DidInventoryUpdate":{"type":"object","properties":{"is_active":{"type":"boolean"},"regulatory_override":{"type":"string","nullable":true,"enum":["api","docs_required"]}}},"AdminIntakePage":{"type":"object","properties":{"data":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"Complianceapprove":{"type":"object","properties":{"note":{"type":"string"}}},"Compliancereject":{"type":"object","properties":{"note":{"type":"string"}}},"CompliancerequestMore":{"type":"object","properties":{"note":{"type":"string"}}},"AdminCdr":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"account_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"call_id":{"type":"string"},"upstream_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"started_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"duration_seconds":{"type":"integer"},"calling":{"type":"string"},"called":{"type":"string"},"status":{"type":"string"},"our_cost":{"$ref":"#/components/schemas/Money"},"customer_charge":{"$ref":"#/components/schemas/Money"},"margin":{"$ref":"#/components/schemas/Money"}},"required":["id","account_id","call_id","upstream_id","started_at","duration_seconds","calling","called","status","our_cost","customer_charge","margin"]},"AdminCdrPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminCdr"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"AdminPayment":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"customer_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"amount":{"$ref":"#/components/schemas/Money"},"status":{"type":"string","enum":["pending","completed","refunded","failed"]},"revolut_order_id":{"type":"string"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","customer_id","amount","status","revolut_order_id","created_at"]},"AdminPaymentPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminPayment"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"AdminRefundCreate":{"type":"object","properties":{"amount":{"allOf":[{"$ref":"#/components/schemas/Money"},{"description":"Omit for full refund."}]},"reason":{"type":"string"}},"required":["reason"]},"AdminCreditCreate":{"type":"object","properties":{"customer_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"amount":{"$ref":"#/components/schemas/Money"},"reason":{"type":"string","minLength":1}},"required":["customer_id","amount","reason"]},"AdminDunningPage":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminCustomer"}},"meta":{"$ref":"#/components/schemas/PageMeta"}},"required":["data","meta"]},"AccountManager":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"name":{"type":"string"},"email":{"type":"string","format":"email"},"is_active":{"type":"boolean"}},"required":["id","name","email","is_active"]},"AccountManagerCreate":{"type":"object","properties":{"name":{"type":"string"},"email":{"type":"string","format":"email"}},"required":["name","email"]},"AdminNoticeCreate":{"type":"object","properties":{"severity":{"type":"string","enum":["info","warning","critical"]},"title":{"type":"string"},"body":{"type":"string"},"starts_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"ends_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["severity","title","body","starts_at"]},"AdminKybStatus":{"type":"string","enum":["open","submitted","approved","rejected"]},"AdminKybListItem":{"type":"object","properties":{"id":{"type":"string"},"account_id":{"type":"string"},"account_legal_name":{"type":"string"},"status":{"$ref":"#/components/schemas/AdminKybStatus"},"submitted_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"reviewer_note":{"type":"string","nullable":true},"document_count":{"type":"integer","minimum":0}},"required":["id","account_id","account_legal_name","status","submitted_at","document_count"]},"AdminKybListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminKybListItem"}},"next_cursor":{"type":"string"}},"required":["items"]},"AdminKybAccountSummary":{"type":"object","properties":{"id":{"type":"string"},"legal_name":{"type":"string"},"trading_name":{"type":"string","nullable":true},"country":{"type":"string"},"contact_name":{"type":"string"},"contact_email":{"type":"string","format":"email"},"status":{"type":"string"}},"required":["id","legal_name","trading_name","country","contact_name","contact_email","status"]},"AdminKybDocument":{"type":"object","properties":{"doc_id":{"type":"string"},"doc_kind":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer","minimum":0},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"download_url":{"type":"string"}},"required":["doc_id","doc_kind","content_type","size_bytes","uploaded_at","download_url"]},"AdminKybDetail":{"type":"object","properties":{"id":{"type":"string"},"account_id":{"type":"string"},"status":{"$ref":"#/components/schemas/AdminKybStatus"},"required_docs":{"type":"array","items":{"type":"string"}},"uploaded_docs":{"type":"array","items":{"type":"string"}},"reviewer_note":{"type":"string","nullable":true},"submitted_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"reviewed_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"account_summary":{"$ref":"#/components/schemas/AdminKybAccountSummary"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/AdminKybDocument"}}},"required":["id","account_id","status","required_docs","uploaded_docs","reviewer_note","submitted_at","reviewed_at","created_at","updated_at","account_summary","documents"]},"AdminKybActionRequest":{"type":"object","properties":{"reviewer_note":{"type":"string","maxLength":2000}}},"AdminBetaAccountStatus":{"type":"string","enum":["beta_signup","beta_card_pending","beta_waitlist","beta_approved","beta_declined","live"]},"AdminBetaKybStatus":{"type":"string","enum":["none","open","submitted","approved","rejected"]},"AdminBetaCardStatus":{"type":"string","enum":["none","pending_verification","completing","verified","verification_failed"]},"AdminBetaListItem":{"type":"object","properties":{"id":{"type":"string","description":"Account id.","example":"acc_0a1b2c3d4e5f6789"},"legal_name":{"type":"string"},"trading_name":{"type":"string","nullable":true},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"contact_email":{"type":"string","format":"email"},"status":{"$ref":"#/components/schemas/AdminBetaAccountStatus"},"waitlist_position":{"type":"integer","nullable":true},"kyb_status":{"$ref":"#/components/schemas/AdminBetaKybStatus"},"card_status":{"$ref":"#/components/schemas/AdminBetaCardStatus"},"traffic_profile_present":{"type":"boolean"},"created_at":{"type":"integer","description":"Unix epoch seconds."}},"required":["id","legal_name","country","contact_email","status","kyb_status","card_status","traffic_profile_present","created_at"]},"AdminBetaListResponse":{"type":"object","properties":{"items":{"type":"array","items":{"$ref":"#/components/schemas/AdminBetaListItem"}},"next_cursor":{"type":"string","description":"Opaque cursor for the next page. Absent when no further pages exist."}},"required":["items"]},"AdminBetaStatsResponse":{"type":"object","properties":{"total":{"type":"integer"},"pending":{"type":"integer","description":"Accounts currently parked in beta_signup, beta_card_pending or beta_waitlist."},"approved_this_week":{"type":"integer","description":"Accounts that transitioned to beta_approved in the last 7 days."},"declined_this_week":{"type":"integer","description":"Accounts that transitioned to beta_declined in the last 7 days."}},"required":["total","pending","approved_this_week","declined_this_week"]},"AdminBetaAccountFull":{"type":"object","properties":{"id":{"type":"string"},"legal_name":{"type":"string"},"trading_name":{"type":"string","nullable":true},"country":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"vat_id":{"type":"string","nullable":true},"contact_name":{"type":"string"},"contact_email":{"type":"string","format":"email"},"contact_phone":{"type":"string","nullable":true},"status":{"$ref":"#/components/schemas/AdminBetaAccountStatus"},"waitlist_position":{"type":"integer","nullable":true},"waitlist_joined_at":{"type":"integer","nullable":true},"reviewer_note":{"type":"string","nullable":true},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}},"required":["id","legal_name","country","contact_name","contact_email","status","created_at","updated_at"]},"AdminBetaTrafficProfile":{"type":"object","nullable":true,"properties":{"estimated_minutes_per_month":{"type":"integer","nullable":true},"target_countries":{"type":"array","items":{"type":"string"}},"traffic_types":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true}},"required":["target_countries","traffic_types"]},"AdminBetaKybSummary":{"type":"object","nullable":true,"properties":{"id":{"type":"string"},"status":{"type":"string","enum":["open","submitted","approved","rejected"]},"required_docs":{"type":"array","items":{"type":"string"}},"uploaded_docs":{"type":"array","items":{"type":"string"}}},"required":["id","status","required_docs","uploaded_docs"]},"AdminBetaPaymentMethodSummary":{"type":"object","nullable":true,"properties":{"status":{"type":"string"},"brand":{"type":"string","nullable":true},"last4":{"type":"string","nullable":true}},"required":["status"]},"AdminBetaDetail":{"type":"object","properties":{"account":{"$ref":"#/components/schemas/AdminBetaAccountFull"},"traffic_profile":{"$ref":"#/components/schemas/AdminBetaTrafficProfile"},"kyb_intake":{"$ref":"#/components/schemas/AdminBetaKybSummary"},"payment_method":{"$ref":"#/components/schemas/AdminBetaPaymentMethodSummary"},"user_emails":{"type":"array","items":{"type":"string","format":"email"}}},"required":["account","traffic_profile","kyb_intake","payment_method","user_emails"]},"AdminBetaActionRequest":{"type":"object","properties":{"reviewer_note":{"type":"string","maxLength":2000,"description":"Optional free-form note shown to the customer in the approval/decline email and stored on the account."}}},"AdminBootstrapResponse":{"type":"object","properties":{"account_id":{"type":"string"},"user_id":{"type":"string"},"message":{"type":"string"}},"required":["account_id","user_id","message"]},"AdminBootstrapRequest":{"type":"object","properties":{"legal_name":{"type":"string","minLength":1,"maxLength":200,"example":"Codus Nullus MB"},"contact_name":{"type":"string","minLength":1,"maxLength":200,"example":"Ops"},"contact_email":{"type":"string","maxLength":200,"format":"email","example":"ops@c0.lt"},"password":{"type":"string","minLength":12,"maxLength":200,"description":"Plaintext password. Hashed with PBKDF2 before storage.","example":"long-enough-bootstrap-pass"}},"required":["legal_name","contact_name","contact_email","password"]},"AuditLogRow":{"type":"object","properties":{"id":{"type":"string"},"ts":{"type":"integer","description":"Unix epoch milliseconds when the action was audited."},"action":{"type":"string"},"account_id":{"type":"string","nullable":true},"user_id":{"type":"string","nullable":true},"actor":{"type":"string","nullable":true,"enum":["customer","admin","system","webhook"],"description":"Who initiated the action. `system` covers cron + automation; `webhook` covers upstream provider callbacks."},"ip":{"type":"string","nullable":true},"user_agent":{"type":"string","nullable":true},"outcome":{"type":"string","enum":["success","failure"]},"reason":{"type":"string","nullable":true},"meta":{"type":"string","nullable":true,"description":"JSON-encoded structured tail. Short values only; never contains secrets."}},"required":["id","ts","action","account_id","user_id","actor","ip","user_agent","outcome","reason","meta"]},"AuditLogListResponse":{"type":"object","properties":{"rows":{"type":"array","items":{"$ref":"#/components/schemas/AuditLogRow"}},"next_cursor":{"type":"string","description":"Opaque cursor for the next page. Absent when the response includes the last row."}},"required":["rows"]},"OperationalDashboard":{"type":"object","properties":{"requests":{"type":"object","properties":{"total":{"type":"integer"},"ts_buckets":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"integer","description":"Bucket start, unix ms, UTC."},"count":{"type":"integer"}},"required":["ts","count"]}},"by_status":{"type":"array","items":{"type":"object","properties":{"status":{"type":"string"},"count":{"type":"integer"}},"required":["status","count"]}}},"required":["total","ts_buckets","by_status"]},"errors":{"type":"object","properties":{"total":{"type":"integer"},"ts_buckets":{"type":"array","items":{"type":"object","properties":{"ts":{"type":"integer","description":"Bucket start, unix ms, UTC."},"count":{"type":"integer"}},"required":["ts","count"]}},"by_route":{"type":"array","items":{"type":"object","properties":{"route":{"type":"string"},"count":{"type":"integer"}},"required":["route","count"]}},"by_account":{"type":"array","items":{"type":"object","properties":{"account_id":{"type":"string"},"count":{"type":"integer"}},"required":["account_id","count"]}}},"required":["total","ts_buckets","by_route","by_account"]},"latency":{"type":"object","nullable":true,"properties":{"p50":{"type":"number"},"p95":{"type":"number"},"p99":{"type":"number"}},"required":["p50","p95","p99"],"description":"Per-request latency p50/p95/p99 over the window. v1 returns null - CF AE does not yet emit request latency through the structured log helper; placeholder kept for the SPA wire-up."},"audit_volume":{"type":"object","properties":{"total":{"type":"integer"},"by_action":{"type":"array","items":{"type":"object","properties":{"action":{"type":"string"},"count":{"type":"integer"}},"required":["action","count"]}}},"required":["total","by_action"]}},"required":["requests","errors","latency","audit_volume"]},"SecurityDashboard":{"type":"object","properties":{"admin_2fa":{"type":"object","properties":{"total_admins":{"type":"integer"},"enrolled":{"type":"integer"},"not_enrolled":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string"},"days_since_admin_role":{"type":"integer","minimum":0,"description":"Whole days since the user's account was created. Voice does not currently track role-grant time separately; `users.created_at` is the closest proxy."}},"required":["user_id","email","days_since_admin_role"]}},"recently_used":{"type":"array","items":{"type":"object","properties":{"user_id":{"type":"string"},"email":{"type":"string"},"last_used_at":{"type":"integer","description":"Unix ms."}},"required":["user_id","email","last_used_at"]},"description":"Admins who have used 2FA in the trailing 30d, newest-first. Recovery-code consumption updates `last_used_at` too, so the field tracks any 2FA challenge - not only TOTP."}},"required":["total_admins","enrolled","not_enrolled","recently_used"]},"failed_signins":{"type":"object","properties":{"last_24h":{"type":"integer"},"last_7d":{"type":"integer"},"hot_accounts":{"type":"array","items":{"type":"object","properties":{"account_id":{"type":"string"},"failure_count":{"type":"integer"}},"required":["account_id","failure_count"]},"description":"Top accounts by failed-signin count in the trailing 24h. Excludes unknown-email failures (no account_id)."}},"required":["last_24h","last_7d","hot_accounts"]},"magic_links":{"type":"object","properties":{"issued_7d":{"type":"integer"},"consumed_7d":{"type":"integer"},"expired_7d":{"type":"integer"},"by_purpose":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"count":{"type":"integer"}},"required":["purpose","count"]}}},"required":["issued_7d","consumed_7d","expired_7d","by_purpose"]},"jwt_rotation":{"type":"object","properties":{"previous_secret_set":{"type":"boolean"},"rotation_active_since":{"type":"integer","nullable":true,"description":"v1 always returns null; the dual-key window has no start-time record. The flag above is the actionable bit."}},"required":["previous_secret_set","rotation_active_since"]}},"required":["admin_2fa","failed_signins","magic_links","jwt_rotation"]},"NoticeCreate":{"type":"object","properties":{"severity":{"type":"string","enum":["info","warning","critical"],"default":"info"},"title":{"type":"string","minLength":1},"body":{"type":"string","minLength":1},"starts_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"ends_at":{"type":"string","nullable":true,"format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["title","body"]}},"parameters":{}},"paths":{"/auth/sign-in":{"post":{"tags":["auth"],"summary":"Sign in with email + password","description":"Returns a session bundle (access JWT + opaque refresh + embedded user profile). Wrong-credentials and unknown-email paths return the same code (auth.password_invalid) to avoid leaking account existence. Accounts in beta_signup or beta_declined cannot sign in; everything from beta_card_pending onwards can.","parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInRequest"}}}},"responses":{"200":{"description":"Session bundle for customer + admin-without-2FA paths. For admin-with-2FA, returns `{ status: '2fa_required', tmp_token }` instead.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignInResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/auth/refresh":{"post":{"tags":["auth"],"summary":"Exchange a refresh token for a fresh session","description":"Rotates the refresh token: consumeRefreshToken atomically marks last_used_at on the presented row, then a new row is inserted. A replayed token returns 401 because the atomic consume fails on the second pass.","parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RefreshRequest"}}}},"responses":{"200":{"description":"Session","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/auth/sign-out":{"post":{"tags":["auth"],"summary":"Revoke the current session","description":"Flips revoked_at on the presented refresh row. Always 204; unknown tokens are no-ops.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SignOutRequest"}}}},"responses":{"204":{"description":"No content"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/auth/forgot-password":{"post":{"tags":["auth"],"summary":"Request a password-reset email","description":"Always returns 202 regardless of whether the email is registered (anti-enumeration). When the address is known, mints a short-lived magic link with purpose=reset and emails the reset URL.","parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}}},"responses":{"202":{"description":"Email queued (always 202 to avoid user enumeration)"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/auth/reset-password":{"post":{"tags":["auth"],"summary":"Complete a password reset","description":"Consumes the reset magic link, hashes the new password, revokes every existing refresh token for the account, and mints a fresh session. The atomic consume guards against replay; wrong-purpose links (e.g. first_login presented here) are rejected.","parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}}},"responses":{"200":{"description":"Session minted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/auth/first-login":{"post":{"tags":["auth"],"summary":"Sign in via the welcome magic link emailed after card-save","description":"Consumes the first-login magic link emailed at signup completion and mints a session. The user may set a password afterwards via /me/password (out of scope for this round).","parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FirstLoginRequest"}}}},"responses":{"200":{"description":"Session minted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SessionResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/beta/signup":{"post":{"tags":["beta"],"summary":"Submit a beta signup","description":"Creates an `accounts` row in `beta_signup` status, the owning `users` row, and a first-login magic link emailed to the contact address. Anti-enumerating: returns the same 202 envelope whether the email was fresh, partway through, or already signed up. Idempotency-Key replays the same response without re-inserting.","parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BetaSignupRequest"}}}},"responses":{"202":{"description":"Welcome email queued. Anti-enumerating envelope.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BetaSignupResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/account":{"get":{"tags":["account"],"summary":"Get the current account profile","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["account"],"summary":"Update the current account profile","description":"Partial update. Omitted fields are left untouched. Writes an audit entry tagged `account.profile.update` listing the patched field names (values are never logged).","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountUpdate"}}}},"responses":{"200":{"description":"Account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Account"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/account/balance":{"get":{"tags":["account"],"summary":"Get current prepaid balance","description":"Returns the current prepaid balance from `accounts.balance_minor`. Topups credit the ledger via the Revolut ORDER_COMPLETED webhook. `minimum`, `soft_warn_threshold`, and `last_debit_at` remain zero / null until plan 0011 telephony lands the prepaid-floor policy and CDR-driven debits.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Balance","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Balance"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/account/quota":{"get":{"tags":["account"],"summary":"Get concurrent-call quota per zone","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Quota list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaList"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/account/asr-acd":{"get":{"tags":["account"],"summary":"Aggregate ASR + ACD over a window","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["24h","7d","30d"],"default":"24h"},"required":false,"name":"period","in":"query"}],"responses":{"200":{"description":"ASR + ACD","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AsrAcd"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/account":{"get":{"tags":["me"],"summary":"Get the signed-in account profile","description":"Returns the slim account projection for the bearer token holder: legal + trading names, contact tuple, country, VAT id, current beta status, and waitlist position (null until the account enters beta_waitlist).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Account.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyAccountResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/waitlist":{"get":{"tags":["me"],"summary":"Get the waitlist position pane","description":"Returns `{ position, total, status }` for the queue tile. `position` is null when the account is still in beta_signup / beta_card_pending (pre-waitlist) or past beta_waitlist (approved / declined / live). `total` is the live count of accounts currently in beta_waitlist.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Waitlist pane.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyWaitlistResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/traffic":{"post":{"tags":["me"],"summary":"Upsert the self-declared traffic profile","description":"Creates or replaces the traffic profile row for the signed-in account. One row per account (UNIQUE account_id), so a subsequent POST with a different body overwrites every mutable column. `Idempotency-Key` replays the original response for 24h.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrafficProfileRequest"}}}},"responses":{"200":{"description":"Traffic profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrafficProfileResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["me"],"summary":"Get the self-declared traffic profile","description":"Returns the traffic profile for the signed-in account, or 404 when none has been declared yet.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Traffic profile.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrafficProfileResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/export":{"get":{"tags":["me"],"summary":"Download a JSON bundle of every record on this account (GDPR Art. 20)","description":"Returns a single application/json bundle containing the account row, every user attached to it, payment-method projections (brand + last4 only - no scheme tokens), KYB intake metadata + per-document URLs (pointing at the bearer-authed /v1/me/kyb/documents/{doc_id} download route), audit-log entries for the account (last 90 days, capped at 10000 rows), and magic-link + refresh-token history (timestamps + ua/ip only - no token hashes).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Data export bundle.","content":{"application/json":{"schema":{"type":"object","properties":{"generated_at":{"type":"integer","description":"Unix epoch milliseconds."},"account":{"type":"object","properties":{"id":{"type":"string"},"legal_name":{"type":"string"},"trading_name":{"type":"string","nullable":true},"country":{"type":"string"},"vat_id":{"type":"string","nullable":true},"contact_name":{"type":"string"},"contact_email":{"type":"string"},"contact_phone":{"type":"string","nullable":true},"status":{"type":"string"},"waitlist_position":{"type":"integer","nullable":true},"waitlist_joined_at":{"type":"integer","nullable":true},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}},"required":["id","legal_name","trading_name","country","vat_id","contact_name","contact_email","contact_phone","status","waitlist_position","waitlist_joined_at","created_at","updated_at"]},"users":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"role":{"type":"string"},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}},"required":["id","email","role","created_at","updated_at"]}},"payment_methods":{"type":"array","items":{"type":"object","properties":{"brand":{"type":"string","nullable":true},"last4":{"type":"string","nullable":true},"exp_month":{"type":"integer","nullable":true},"exp_year":{"type":"integer","nullable":true},"status":{"type":"string"},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}},"required":["brand","last4","exp_month","exp_year","status","created_at","updated_at"]}},"kyb_intakes":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"required_docs":{"type":"array","items":{"type":"string"}},"uploaded_docs":{"type":"array","items":{"type":"string"}},"reviewer_note":{"type":"string","nullable":true},"submitted_at":{"type":"integer","nullable":true},"reviewed_at":{"type":"integer","nullable":true},"created_at":{"type":"integer"},"updated_at":{"type":"integer"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"doc_kind":{"type":"string"},"content_type":{"type":"string"},"size_bytes":{"type":"integer"},"uploaded_at":{"type":"integer"},"signed_url":{"type":"string","nullable":true,"format":"uri"}},"required":["id","doc_kind","content_type","size_bytes","uploaded_at","signed_url"]}}},"required":["id","status","required_docs","uploaded_docs","reviewer_note","submitted_at","reviewed_at","created_at","updated_at","documents"]}},"magic_link_history":{"type":"array","items":{"type":"object","properties":{"purpose":{"type":"string"},"created_at":{"type":"integer"},"expires_at":{"type":"integer"},"consumed_at":{"type":"integer","nullable":true}},"required":["purpose","created_at","expires_at","consumed_at"]}},"refresh_token_history":{"type":"array","items":{"type":"object","properties":{"created_at":{"type":"integer"},"expires_at":{"type":"integer"},"revoked_at":{"type":"integer","nullable":true},"last_used_at":{"type":"integer","nullable":true},"user_agent":{"type":"string","nullable":true},"ip":{"type":"string","nullable":true}},"required":["created_at","expires_at","revoked_at","last_used_at","user_agent","ip"]}},"audit_log":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"ts":{"type":"integer"},"action":{"type":"string"},"actor":{"type":"string","nullable":true},"outcome":{"type":"string"},"reason":{"type":"string","nullable":true},"ip":{"type":"string","nullable":true},"user_agent":{"type":"string","nullable":true},"meta":{"type":"string","nullable":true}},"required":["id","ts","action","actor","outcome","reason","ip","user_agent","meta"]},"description":"Audit log entries scoped to this account, last 90 days, capped at 10000 rows."}},"required":["generated_at","account","users","payment_methods","kyb_intakes","magic_link_history","refresh_token_history","audit_log"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/delete-request":{"post":{"tags":["me"],"summary":"Request account deletion (GDPR Art. 17)","description":"Records a pending deletion request, mints a 1h magic link with purpose=delete_confirm, and emails the customer a confirmation URL. Caller must retype their own email in `confirm_email` to guard against misclicks. Returns 202 with the deletion-request id + the link's expires_at; the magic-link plaintext is delivered only via the email body.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"confirm_email":{"type":"string","format":"email","description":"Must equal the signed-in user's email address."}},"required":["confirm_email"]}}}},"responses":{"202":{"description":"Deletion request recorded; confirmation email queued.","content":{"application/json":{"schema":{"type":"object","properties":{"deletion_request_id":{"type":"string"},"expires_at":{"type":"integer","description":"Unix epoch milliseconds."}},"required":["deletion_request_id","expires_at"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/delete-confirm":{"post":{"tags":["me"],"summary":"Confirm + execute account deletion","description":"Public endpoint (no auth) - customer may be signed out or on a different device. Consumes the delete_confirm magic link, looks up the pending deletion_request, then anonymizes the user + redacts the account + hard-deletes payment methods + magic links + refresh tokens + KYB document PDFs. KYB intake metadata + audit log + the account row itself are retained. Sessions are revoked.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"token":{"type":"string","minLength":1}},"required":["token"]}}}},"responses":{"200":{"description":"Account deleted.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["deleted"]}},"required":["status"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/delete-cancel":{"post":{"tags":["me"],"summary":"Cancel a pending deletion request","description":"Marks the latest pending deletion_request for this account as 'cancelled'. The emailed magic link remains technically valid until its 1h TTL elapses but cannot be acted on because the deletion_request row is no longer pending. Returns 200 even when there was no pending request, so a double-cancel is a safe no-op for the caller.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{},"additionalProperties":false}}}},"responses":{"200":{"description":"Cancellation recorded.","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["cancelled"]}},"required":["status"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/kyb":{"get":{"tags":["kyb"],"summary":"Get (or create) the KYB intake for the signed-in account","description":"Returns the current KYB intake for the account. If no intake exists yet, creates one in 'open' status pre-loaded with the wholesale required-docs checklist, then returns it.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"ComplianceIntake","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceIntake"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/kyb/documents":{"post":{"tags":["kyb"],"summary":"Upload a KYB document (multipart)","description":"Multipart fields: `doc_kind` (must be one of the intake's required_docs) and `file` (PDF or jpg/png/webp, up to 10MB). Stored in R2 under `kyb-documents/{account_id}/{intake_id}/{doc_id}.{ext}`. Inserts a `kyb_intake_documents` row and idempotently appends doc_kind to the intake's `uploaded_docs` list.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"doc_kind":{"type":"string"},"file":{"type":"string","format":"binary"}},"required":["doc_kind","file"]}}}},"responses":{"201":{"description":"Document stored.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KybUploadResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Intake is not in 'open' status.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"413":{"description":"Uploaded file exceeds 10MB.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"415":{"description":"Content type not in {pdf, jpg, png, webp}.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/kyb/submit":{"post":{"tags":["kyb"],"summary":"Submit the KYB intake for admin review","description":"Transitions the intake from 'open' to 'submitted'. Requires every doc in `required_docs` to appear in `uploaded_docs`; otherwise returns 422 with code `compliance.missing_required_docs`. Emits the `kybSubmittedEmail` notification so the customer sees an ack while admins are reviewing.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"responses":{"200":{"description":"Updated intake.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ComplianceIntake"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"No KYB intake found for this account.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"409":{"description":"Intake is not in 'open' status.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/kyb/documents/{doc_id}":{"get":{"tags":["kyb"],"summary":"Stream a previously-uploaded KYB document","description":"Streams the raw bytes back from R2, with the Content-Type captured at upload time. 404 when the document does not exist, or when it belongs to a different account than the caller.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"doc_id","in":"path"}],"responses":{"200":{"description":"Document bytes (raw stream; Content-Type per upload).","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown document id, or document belongs to another account.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payment-methods":{"get":{"tags":["billing"],"summary":"List saved payment methods","description":"Returns every `verified` payment_methods row for the calling account, ordered with the default card first. In-flight rows (`pending_verification`, `completing`, `verification_failed`) are excluded - those lack card-detail columns. SPAs that need to render an in-flight save-card chip should call `GET /v1/me/payment-method`.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Methods","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PaymentMethod"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["billing"],"summary":"Begin saving a new payment method","description":"Opens (or reuses) a Revolut manual-capture hosted-checkout flow with `save_payment_method_for=merchant`. Returns the hosted-checkout URL the SPA should redirect to; the saved-method row is finalised by the verification webhook. Idempotency-Key replays the original response for 24h. Mirror of POST /v1/payment-methods/setup with a return_url body + an `order_id` field on the response (matches the OpenAPI PaymentMethodCreateResponse contract).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodCreateRequest"}}}},"responses":{"200":{"description":"Checkout link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethodCreateResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payment-methods/{id}":{"delete":{"tags":["billing"],"summary":"Remove a saved payment method","description":"Soft-delete (status -> 'deleted'). The row remains referenced by past topups + invoices but is hidden from GET /payment-methods. 404 when the id is not a verified row owned by the caller.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Removed"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payment-methods/{id}/default":{"post":{"tags":["billing"],"summary":"Mark a saved method as default","description":"Promotes the named `verified` payment_methods row to default and clears `is_default` on every other row for the calling account. Two-statement D1 batch so the single-default invariant survives concurrent calls. 404 if the id is not a verified row owned by the caller.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Updated method","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PaymentMethod"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payments/topups":{"post":{"tags":["billing"],"summary":"Initiate a prepaid top-up","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupLiveRequest"}}}},"responses":{"200":{"description":"Topup created on Revolut","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupLiveResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["billing"],"summary":"List top-ups","description":"Cursor-paginated list of topups for the caller, newest first. `meta.next_cursor` is null when no further pages exist. Default limit 50, max 200 (enforced by the shared PaginationQuery schema).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Topups","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TopupPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payments/topups/{id}":{"get":{"tags":["billing"],"summary":"Get a single top-up","description":"404 when the id does not belong to the caller's account.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Topup","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Topup"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payments/auto-recharge":{"get":{"tags":["billing"],"summary":"Get auto-recharge settings","description":"Returns the persisted auto-recharge settings, or the disabled-by-default envelope when no row exists yet.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRecharge"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["billing"],"summary":"Update auto-recharge settings","description":"Upserts the auto-recharge row for the caller. Writes a `billing.auto_recharge.update` audit entry with the new enabled state.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRecharge"}}}},"responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoRecharge"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payments/low-balance-notify":{"get":{"tags":["billing"],"summary":"Get low-balance notification settings","description":"Returns the persisted setting, or the disabled-by-default envelope (`enabled=false, threshold_pct=30`) when no row exists yet.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LowBalanceNotify"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["billing"],"summary":"Update low-balance notification settings","description":"Upserts the low-balance-notify row. Writes a `billing.low_balance_notify.update` audit entry.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LowBalanceNotify"}}}},"responses":{"200":{"description":"Settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LowBalanceNotify"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/invoices":{"get":{"tags":["billing"],"summary":"List invoices","description":"Paginated list of invoices for the caller's account, newest first. Pagination uses the standard page + page_size query params; `total` is the unfiltered row count.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Invoices","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InvoicePage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/invoices/{id}":{"get":{"tags":["billing"],"summary":"Get a single invoice","description":"404 when the id does not belong to the caller's account.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/invoices/{id}/pdf":{"get":{"tags":["billing"],"summary":"Get invoice PDF","description":"Streams the rendered invoice PDF inline. Reads from R2 when `invoices.pdf_r2_key` is set; otherwise renders the PDF on demand via @codus-nullus/billing-primitives, uploads to R2, and persists the key so the next request skips the renderer. 503 when the `INVOICES_R2` binding is missing (local dev without R2 bound).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","description":"BCP 47 tag. Honored only on endpoints that emit user-visible text (rare; mostly server-rendered templates)."},"required":false,"name":"Accept-Language","in":"header"}],"responses":{"200":{"description":"PDF","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/vat":{"get":{"tags":["billing"],"summary":"Get VAT status","description":"Returns the persisted VAT status + id for the caller's account. Status is hydrated from the `accounts.vat_status` column (migration 0014). VAT-proof document ids ship empty until POST /vat/proof lands (STOP-deferred in plan 0031).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"VAT","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VatStatus"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/vat/proof":{"post":{"tags":["billing"],"summary":"Upload VAT exemption proof","description":"Multipart upload of a single VAT exemption proof document. Accepted MIME types: application/pdf, image/jpeg, image/png. Max 10MB. Persists the R2 object under `account_<account_id>/vat_proof_<unix_seconds>.<ext>`, records the key on `accounts.vat_proof_r2_key`, and moves the account into `vat_status='pending'` (operator review required). Returns 201 with the updated VAT status envelope.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"file":{"type":"string","format":"binary"}},"required":["file"]}}}},"responses":{"201":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VatStatus"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trunks":{"get":{"tags":["trunks"],"summary":"List trunks","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Trunks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrunkPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["trunks"],"summary":"Create a trunk","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrunkCreate"}}}},"responses":{"201":{"description":"Trunk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trunk"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trunks/{id}":{"get":{"tags":["trunks"],"summary":"Get a trunk","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Trunk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trunk"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["trunks"],"summary":"Update a trunk","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrunkUpdate"}}}},"responses":{"200":{"description":"Trunk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Trunk"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["trunks"],"summary":"Delete a trunk","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/trunks/{id}/dids":{"get":{"tags":["trunks"],"summary":"List DIDs assigned to a trunk","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"DIDs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TrunkDidPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/ip-allowlist":{"get":{"tags":["ip-allowlist"],"summary":"List allowed source IPs","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Entries","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/IpAllowEntry"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["ip-allowlist"],"summary":"Add an allowed source IP/CIDR","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IpAllowCreate"}}}},"responses":{"201":{"description":"Entry","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IpAllowEntry"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/ip-allowlist/{id}":{"delete":{"tags":["ip-allowlist"],"summary":"Remove an allowed source IP/CIDR","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Removed"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/fraud-caps":{"get":{"tags":["fraud-caps"],"summary":"Get fraud caps","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Caps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FraudCaps"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"put":{"tags":["fraud-caps"],"summary":"Update fraud caps","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/FraudCaps"}}}},"responses":{"200":{"description":"Caps","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FraudCaps"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/numbers/inventory":{"get":{"tags":["numbers"],"summary":"Search available DID inventory","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"required":false,"name":"country","in":"query"},{"schema":{"type":"string","enum":["local","tollfree","mobile"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","description":"Comma-separated, e.g. voice,sms"},"required":false,"name":"capabilities","in":"query"}],"responses":{"200":{"description":"Inventory","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InventoryPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/numbers/orders":{"post":{"tags":["numbers"],"summary":"Order a DID from inventory","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberOrderCreate"}}}},"responses":{"201":{"description":"Order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberOrder"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"get":{"tags":["numbers"],"summary":"List number orders","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Orders","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberOrderPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/numbers/orders/{id}":{"get":{"tags":["numbers"],"summary":"Get a number order","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Order","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NumberOrder"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["numbers"],"summary":"Cancel a pending number order","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Cancelled"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/dids":{"get":{"tags":["numbers"],"summary":"List owned DIDs","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"DIDs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DidPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/dids/{id}":{"get":{"tags":["numbers"],"summary":"Get a DID","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"DID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Did"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["numbers"],"summary":"Move a DID to another trunk","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DidUpdate"}}}},"responses":{"200":{"description":"DID","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Did"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["numbers"],"summary":"Release a DID","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Released"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/compliance/intakes":{"get":{"tags":["compliance"],"summary":"List compliance intakes","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Intakes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IntakePage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/compliance/intakes/{id}":{"get":{"tags":["compliance"],"summary":"Get a compliance intake","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Intake","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/compliance/intakes/{id}/documents":{"post":{"tags":["compliance"],"summary":"Upload a document to an intake","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"kind":{"type":"string","example":"passport"},"file":{"type":"string","format":"binary"}},"required":["kind","file"]}}}},"responses":{"202":{"description":"Intake","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/cdr":{"get":{"tags":["cdr"],"summary":"List CDRs","description":"Default retention: 90 days online; older rows return 410 with errors.cdr.archived (request an export instead).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"required":false,"name":"country","in":"query"},{"schema":{"type":"string"},"required":false,"name":"destination_prefix","in":"query"},{"schema":{"type":"string","enum":["answered","no_answer","busy","failed","cancelled"]},"required":false,"name":"status","in":"query"},{"schema":{"type":"number","nullable":true,"minimum":0,"maximum":1},"required":false,"name":"min_asr","in":"query"},{"schema":{"type":"integer","nullable":true},"required":false,"name":"min_acd","in":"query"}],"responses":{"200":{"description":"CDRs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/cdr/summary":{"get":{"tags":["cdr"],"summary":"Per-day per-country/per-network CDR rollup","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"date","example":"2026-05-13"},"required":true,"name":"date","in":"query"}],"responses":{"200":{"description":"Summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrSummary"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/cdr/{id}":{"get":{"tags":["cdr"],"summary":"Get a single CDR","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"CDR","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Cdr"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/cdr/exports":{"post":{"tags":["cdr"],"summary":"Request a CDR export","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrExportCreate"}}}},"responses":{"202":{"description":"Export queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrExport"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/cdr/exports/{id}":{"get":{"tags":["cdr"],"summary":"Poll a CDR export","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrExport"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/capacity":{"get":{"tags":["capacity"],"summary":"Concurrent-call peaks over a period","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["week","month"],"default":"week"},"required":false,"name":"period","in":"query"}],"responses":{"200":{"description":"Capacity","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Capacity"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/rates":{"get":{"tags":["rates"],"summary":"Customer-facing rate deck (single deck v1)","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"required":false,"name":"country","in":"query"}],"responses":{"200":{"description":"Rates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RatePage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/rates/diff":{"get":{"tags":["rates"],"summary":"Rate-deck diff between two dates","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"date"},"required":true,"name":"from","in":"query"},{"schema":{"type":"string","format":"date"},"required":true,"name":"to","in":"query"}],"responses":{"200":{"description":"Diff","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/RateDiffEntry"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tickets":{"get":{"tags":["tickets"],"summary":"List support tickets","description":"The caller's account's tickets, newest-updated first. No message threads.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Tickets","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["tickets"],"summary":"Open a support ticket","description":"Creates the ticket plus its first customer message in one call. Status starts at 'open'.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketCreate"}}}},"responses":{"201":{"description":"Ticket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tickets/{id}":{"get":{"tags":["tickets"],"summary":"Get a ticket with its message thread","description":"404 when the id does not belong to the caller's account.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Ticket","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Ticket"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/tickets/{id}/messages":{"post":{"tags":["tickets"],"summary":"Reply to a ticket","description":"Appends a customer message, bumps updated_at, and moves the ticket to 'pending_team'. 404 when the ticket is not owned by the caller's account.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessageCreate"}}}},"responses":{"201":{"description":"Message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TicketMessage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/notices":{"get":{"tags":["notices"],"summary":"List active server-curated notices","description":"Notices whose window covers the current time, newest first.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Notices","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Notice"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/notifications":{"get":{"tags":["me"],"summary":"List the current user's notifications","description":"Paginated list of the caller's notifications, newest first.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Notifications","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/notifications/{id}/read":{"post":{"tags":["me"],"summary":"Mark a notification as read","description":"Idempotent. 404 when the id does not belong to the caller's account.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Marked read"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/notifications/mark-all-read":{"post":{"tags":["me"],"summary":"Mark every notification as read","description":"Idempotent bulk UPDATE; safe to call when no unread rows exist.","security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Marked read"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/webhooks/revolut":{"post":{"tags":["webhooks"],"summary":"Revolut Merchant API webhook receiver","description":"Verifies Revolut-Signature (HMAC-SHA256 over `v1.{timestamp}.{rawBody}`) plus 5-minute freshness window before processing. Card-verify completions assign waitlist positions and email the customer; failures mark the payment-method row failed and leave the account in `beta_card_pending` for retry. Redelivered payloads dedupe via the `idempotency_keys` table.","parameters":[{"schema":{"type":"string","example":"v1=abcdef..."},"required":true,"name":"Revolut-Signature","in":"header"},{"schema":{"type":"string","example":"1747200000000"},"required":true,"name":"Revolut-Request-Timestamp","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":{"nullable":true}}}}},"responses":{"200":{"description":"Accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RevolutWebhookAck"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/payment-methods/setup":{"post":{"tags":["payment-methods"],"summary":"Open (or reopen) a Revolut card-verify checkout for the calling account","description":"Authenticated. Mints a manual-capture Revolut order with save_payment_method_for=merchant and returns the hosted-checkout URL. Transitions accounts in beta_signup to beta_card_pending. When a pending_verification payment-method row already exists for the account, we reuse its Revolut order rather than mint a second one. 409 if the account is already past the card-pending stage.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardSetupRequest"}}}},"responses":{"200":{"description":"Checkout URL minted (or replayed).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CardSetupResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/me/payment-method":{"get":{"tags":["payment-methods"],"summary":"Read the calling account's saved (or in-flight) payment method","description":"Returns the most-recent payment-methods row for the authenticated account. Card-detail columns (brand/last4/exp_*) are NULL while the row is in pending_verification or completing; they fill in once the verification webhook lands. 404 if the account has never opened a card-verify flow.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Payment method (in-flight or verified).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MyPaymentMethodResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/customers":{"get":{"tags":["admin/customers"],"summary":"Search customers","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","description":"Free-text search over company / email / VAT id."},"required":false,"name":"q","in":"query"},{"schema":{"$ref":"#/components/schemas/OnboardingStatus"},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Customers","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/customers/{id}":{"get":{"tags":["admin/customers"],"summary":"Get a customer","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Customer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomer"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["admin/customers"],"summary":"Update a customer (status transition, AM assignment)","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomerUpdate"}}}},"responses":{"200":{"description":"Customer","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCustomer"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/customers/{id}/impersonate":{"post":{"tags":["admin/customers"],"summary":"Issue a short-lived read-only impersonation token","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminImpersonateResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/customers/{id}/notes":{"get":{"tags":["admin/customers"],"summary":"List internal notes for a customer","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Notes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNotePage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin/customers"],"summary":"Add an internal note","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNoteCreate"}}}},"responses":{"201":{"description":"Note","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNote"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/onboarding/queue":{"get":{"tags":["admin/onboarding"],"summary":"Onboarding work queue","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"$ref":"#/components/schemas/OnboardingStatus"},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Queue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOnboardingPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/upstreams":{"get":{"tags":["admin/upstreams"],"summary":"List upstream providers","security":[{"bearerAuthAdmin":[]}],"responses":{"200":{"description":"Upstreams","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Upstream"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin/upstreams"],"summary":"Add an upstream provider","security":[{"bearerAuthAdmin":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpstreamCreate"}}}},"responses":{"201":{"description":"Upstream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upstream"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/upstreams/{id}":{"get":{"tags":["admin/upstreams"],"summary":"Get an upstream","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Upstream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upstream"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"patch":{"tags":["admin/upstreams"],"summary":"Update an upstream","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpstreamUpdate"}}}},"responses":{"200":{"description":"Upstream","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upstream"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"delete":{"tags":["admin/upstreams"],"summary":"Remove an upstream","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Removed"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/upstreams/{id}/import-rates":{"post":{"tags":["admin/upstreams"],"summary":"Trigger an immediate rate import","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"responses":{"202":{"description":"Import queued"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/rates":{"get":{"tags":["admin/rates"],"summary":"List per-upstream raw rates","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":false,"name":"upstream","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"required":false,"name":"country","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"required":false,"name":"effective_at","in":"query"}],"responses":{"200":{"description":"Rates","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRatePage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/did-inventory":{"get":{"tags":["admin/did-inventory"],"summary":"List DID inventory rows","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","minLength":2,"maxLength":2,"pattern":"^[A-Z]{2}$","description":"ISO 3166-1 alpha-2 country code.","example":"LT"},"required":false,"name":"country","in":"query"},{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":false,"name":"upstream","in":"query"}],"responses":{"200":{"description":"Rows","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DidInventoryPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/did-inventory/import":{"post":{"tags":["admin/did-inventory"],"summary":"Import DID inventory CSV for an upstream","security":[{"bearerAuthAdmin":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"upstream_id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"file":{"type":"string","format":"binary"}},"required":["upstream_id","file"]}}}},"responses":{"202":{"description":"Import queued"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/did-inventory/{id}":{"patch":{"tags":["admin/did-inventory"],"summary":"Edit a DID inventory row","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DidInventoryUpdate"}}}},"responses":{"200":{"description":"Row","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DidInventoryRow"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/compliance/queue":{"get":{"tags":["admin/compliance"],"summary":"Compliance review queue","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Intakes","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminIntakePage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/compliance/intakes/{id}/approve":{"post":{"tags":["admin/compliance"],"summary":"Compliance review action: approve","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Complianceapprove"}}}},"responses":{"200":{"description":"Intake","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/compliance/intakes/{id}/reject":{"post":{"tags":["admin/compliance"],"summary":"Compliance review action: reject","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Compliancereject"}}}},"responses":{"200":{"description":"Intake","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/compliance/intakes/{id}/request-more":{"post":{"tags":["admin/compliance"],"summary":"Compliance review action: request-more","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CompliancerequestMore"}}}},"responses":{"200":{"description":"Intake","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/ComplianceIntake"},{"properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"status":{"type":"string","enum":["draft","submitted","under_review","approved","rejected","more_info_requested"]},"purpose":{"type":"string","enum":["kyb","regulatory_did"]},"related_resource_id":{"type":"string","nullable":true,"format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"documents":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"kind":{"type":"string"},"filename":{"type":"string"},"uploaded_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"status":{"type":"string","enum":["pending","accepted","rejected"]},"reject_reason":{"type":"string"}},"required":["id","kind","filename","uploaded_at","status"]}},"created_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"updated_at":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"}},"required":["id","status","purpose","related_resource_id","documents","created_at","updated_at"]}]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/compliance/intakes/{id}/notes":{"post":{"tags":["admin/compliance"],"summary":"Add an internal note to an intake","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNoteCreate"}}}},"responses":{"201":{"description":"Note","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminNote"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/cdr":{"get":{"tags":["admin/cdr"],"summary":"Cross-customer CDR search","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":false,"name":"customer_id","in":"query"},{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":false,"name":"upstream_id","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","description":"ISO 8601 UTC timestamp","example":"2026-05-14T09:30:00Z"},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"CDRs","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCdrPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/cdr/exports":{"post":{"tags":["admin/cdr"],"summary":"Request a cross-customer CDR export","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrExportCreate"}}}},"responses":{"202":{"description":"Export queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrExport"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/cdr/exports/{id}":{"get":{"tags":["admin/cdr"],"summary":"Poll an admin CDR export","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Export","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CdrExport"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/payments":{"get":{"tags":["admin/payments"],"summary":"List payments (cross-customer)","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":false,"name":"customer_id","in":"query"},{"schema":{"type":"string","enum":["pending","completed","refunded","failed"]},"required":false,"name":"status","in":"query"}],"responses":{"200":{"description":"Payments","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPaymentPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/payments/{id}/refund":{"post":{"tags":["admin/payments"],"summary":"Refund a payment","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminRefundCreate"}}}},"responses":{"202":{"description":"Refund queued","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPayment"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/credits":{"post":{"tags":["admin/payments"],"summary":"Issue a manual credit","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminCreditCreate"}}}},"responses":{"201":{"description":"Credit applied"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/dunning/queue":{"get":{"tags":["admin/dunning"],"summary":"Wholesale dunning queue (state-machine view)","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","description":"Cursor returned by the previous page's meta.next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Queue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDunningPage"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/account-managers":{"get":{"tags":["admin/account-managers"],"summary":"List account managers","security":[{"bearerAuthAdmin":[]}],"responses":{"200":{"description":"Managers","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AccountManager"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin/account-managers"],"summary":"Create an account manager","security":[{"bearerAuthAdmin":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountManagerCreate"}}}},"responses":{"201":{"description":"Manager","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountManager"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/account-managers/{id}":{"delete":{"tags":["admin/account-managers"],"summary":"Deactivate an account manager","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deactivated"},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/notices":{"get":{"tags":["admin/notices"],"summary":"Admin: list all notices","description":"Every notice, newest-created first, including future and expired ones.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Notices.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Notice"}}},"required":["data"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}},"post":{"tags":["admin/notices"],"summary":"Admin: create a notice","description":"starts_at defaults to now when omitted; ends_at null means open-ended.","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NoticeCreate"}}}},"responses":{"201":{"description":"Notice.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Notice"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/notices/{id}":{"delete":{"tags":["admin/notices"],"summary":"Admin: delete a notice","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid","example":"0e8b4a26-2b8f-4f7f-9b34-3a4a8f3a3a11"},"required":true,"name":"id","in":"path"}],"responses":{"204":{"description":"Deleted."},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/kyb":{"get":{"tags":["admin/kyb"],"summary":"Admin: KYB review queue","description":"Cursor-paginated list of KYB intakes, newest submitted first. Default page size 25, max 100.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"allOf":[{"$ref":"#/components/schemas/AdminKybStatus"},{"description":"Optional status filter. Omit to return every intake."}]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","description":"Opaque cursor returned in the previous response's `next_cursor`."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":25,"example":25},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Queue page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKybListResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/kyb/{id}":{"get":{"tags":["admin/kyb"],"summary":"Admin: KYB intake detail","description":"Returns the intake, the owning account summary, and per-document metadata in one call.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Intake detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKybDetail"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/kyb/documents/{doc_id}":{"get":{"tags":["admin/kyb"],"summary":"Admin: stream a KYB document from R2","description":"Streams the file bytes inline with the original Content-Type. Admin auth gate only; the per-intake ownership check is implicit (admins see every intake).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"doc_id","in":"path"}],"responses":{"200":{"description":"File bytes.","content":{"*/*":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/kyb/{id}/approve":{"post":{"tags":["admin/kyb"],"summary":"Admin: approve a KYB intake","description":"Atomically flips the intake from 'submitted' to 'approved', stamps reviewed_at + reviewer_note, and emails the account contact. Idempotency-Key replays the same response.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKybActionRequest"}}}},"responses":{"200":{"description":"Decided intake.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKybDetail"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/kyb/{id}/reject":{"post":{"tags":["admin/kyb"],"summary":"Admin: reject a KYB intake","description":"Atomically flips the intake from 'submitted' to 'rejected', stamps reviewed_at + reviewer_note, and emails the account contact. The customer can open a fresh intake afterwards.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKybActionRequest"}}}},"responses":{"200":{"description":"Decided intake.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminKybDetail"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/beta":{"get":{"tags":["admin/beta"],"summary":"Cursor-paginated beta queue","description":"Lists beta-funnel accounts with summary KYB / card / traffic-profile status. Defaults to ordering by waitlist_position ASC (NULLs last), then created_at DESC. Filter with `status`, page with `cursor` + `limit`.","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"allOf":[{"$ref":"#/components/schemas/AdminBetaAccountStatus"},{"description":"Filter by exact account status."}]},"required":false,"name":"status","in":"query"},{"schema":{"type":"string","description":"Cursor returned by the previous page."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Beta accounts page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaListResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/beta/stats":{"get":{"tags":["admin/beta"],"summary":"Beta queue dashboard counters","description":"Returns total accounts, currently-pending count (beta_signup + beta_card_pending + beta_waitlist), and approved/declined counts over the last 7 days (based on accounts.updated_at).","security":[{"bearerAuthAdmin":[]}],"responses":{"200":{"description":"Beta stats.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaStatsResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/beta/{id}":{"get":{"tags":["admin/beta"],"summary":"Beta account detail","description":"Returns the full account row plus the latest traffic profile, latest KYB intake summary, latest payment-method summary, and the list of portal user emails on the account.","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Beta detail.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaDetail"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown account id."},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/beta/{id}/approve":{"post":{"tags":["admin/beta"],"summary":"Approve a beta waitlist account","description":"Atomically transitions an account from `beta_waitlist` to `beta_approved`, stores an optional reviewer note, and emails the customer. Returns 409 `admin.beta_not_actionable` if the account is not currently on the waitlist. Idempotent via Idempotency-Key.","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaActionRequest"}}}},"responses":{"200":{"description":"Approved account snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaListItem"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown account."},"409":{"description":"Account is not on the waitlist."},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/beta/{id}/decline":{"post":{"tags":["admin/beta"],"summary":"Decline a beta waitlist account","description":"Atomically transitions an account from `beta_waitlist` to `beta_declined`, stores an optional reviewer note, and emails the customer. Returns 409 `admin.beta_not_actionable` if the account is not currently on the waitlist. Idempotent via Idempotency-Key.","security":[{"bearerAuthAdmin":[]}],"parameters":[{"schema":{"type":"string"},"required":true,"name":"id","in":"path"},{"schema":{"type":"string","format":"uuid","description":"UUID. Required for any mutation that creates a chargeable side effect or external write. Server replays the original response for 24h on a repeat key."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaActionRequest"}}}},"responses":{"200":{"description":"Declined account snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBetaListItem"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"404":{"description":"Unknown account."},"409":{"description":"Account is not on the waitlist."},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/bootstrap":{"post":{"tags":["admin/bootstrap"],"summary":"Mint the first admin user (one-shot)","description":"Gated by `Authorization: Bearer <ADMIN_BOOTSTRAP_SECRET>`. Mints an accounts row (status='live', country='LT') + users row (role='admin'). Returns 403 if any admin user already exists - this endpoint never enables minting a second admin.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBootstrapRequest"}}}},"responses":{"201":{"description":"Admin user created.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminBootstrapResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/audit":{"get":{"tags":["admin/audit"],"summary":"Admin: audit log listing","description":"Cursor-paginated newest-first listing of the durable D1 audit_log table. The companion AE side-channel (`APP_AUDIT`) is the fast-query 90-day stream; this endpoint is the 7-year durable record.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","description":"Filter to a single account id (exact match)."},"required":false,"name":"account_id","in":"query"},{"schema":{"type":"string","description":"Filter to a single action namespace (exact match)."},"required":false,"name":"action","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Inclusive lower bound on ts, unix epoch milliseconds."},"required":false,"name":"since","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Inclusive upper bound on ts, unix epoch milliseconds."},"required":false,"name":"until","in":"query"},{"schema":{"type":"string","description":"Opaque cursor from the previous response's next_cursor."},"required":false,"name":"cursor","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":200,"default":50,"example":50},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Audit log page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditLogListResponse"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/2fa/enroll":{"post":{"tags":["admin/2fa"],"summary":"Enroll the signed-in admin in TOTP 2FA","description":"Generates a fresh TOTP secret + 10 recovery codes for the signed-in admin. Returns the secret, otpauth URI, an externally-rendered QR PNG URL, and the plaintext recovery codes ONCE. The DB stores SHA-256 hashes of the recovery codes; plaintext cannot be recovered.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Enrollment data. Show ONCE.","content":{"application/json":{"schema":{"type":"object","properties":{"secret":{"type":"string","description":"Base32 TOTP seed. Show once."},"totp_uri":{"type":"string","description":"otpauth:// URI for QR rendering."},"qr_url":{"type":"string","format":"uri","description":"PNG QR code URL the SPA can render as <img src>."},"recovery_codes":{"type":"array","items":{"type":"string"},"description":"Plaintext recovery codes. Show once; the DB stores SHA-256 hashes."}},"required":["secret","totp_uri","qr_url","recovery_codes"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/2fa/verify":{"post":{"tags":["admin/2fa"],"summary":"Verify a TOTP code and exchange the tmp_token for a session","description":"Consumes the tmp_token minted by /v1/auth/sign-in for an admin with 2FA enabled. On success, mints the real (access JWT + refresh) session. Wrong codes are rate-limited at the auth layer; reuse of an already-verified tmp_token is rejected because each verify mints a fresh refresh row but the tmp_token validity period is short.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tmp_token":{"type":"string","minLength":1},"code":{"type":"string","minLength":6,"maxLength":6}},"required":["tmp_token","code"]}}}},"responses":{"200":{"description":"Session minted.","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"expires_at":{"type":"integer"},"refresh_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"account_id":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}}},"required":["id","email","account_id","roles"]}},"required":["access_token","expires_at","refresh_token","token_type","user"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/2fa/recovery-code":{"post":{"tags":["admin/2fa"],"summary":"Consume a recovery code to bypass TOTP","description":"Same flow as /verify but consumes a one-shot recovery code. The presented code is SHA-256 hashed and compared in constant time against every remaining stored hash. On a hit, the matching hash is removed from the stored list and the row's last_used_at is bumped. When all codes are consumed, the row stays in place; the admin must re-enroll on their next sign-in (operator policy enforced by the SPA + this endpoint returning an empty recovery_codes hint on enroll).","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tmp_token":{"type":"string","minLength":1},"code":{"type":"string","minLength":1}},"required":["tmp_token","code"]}}}},"responses":{"200":{"description":"Session minted.","content":{"application/json":{"schema":{"type":"object","properties":{"access_token":{"type":"string"},"expires_at":{"type":"integer"},"refresh_token":{"type":"string"},"token_type":{"type":"string","enum":["Bearer"]},"user":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"account_id":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}}},"required":["id","email","account_id","roles"]}},"required":["access_token","expires_at","refresh_token","token_type","user"]}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/2fa":{"delete":{"tags":["admin/2fa"],"summary":"Delete the signed-in admin's 2FA enrollment (testing only)","description":"Removes the admin_2fa row for the signed-in user. Intended for testing and for the operator's bootstrap pass during the 7-day-to-enroll window after C3 deploy. In production a re-enrollment flow (lose a device -> use a recovery code -> re-enroll) is preferred over delete + re-enroll.","security":[{"bearerAuth":[]}],"responses":{"204":{"description":"Enrollment removed."},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}},"/admin/dashboard/operational":{"get":{"tags":["admin"],"summary":"Admin: operational dashboard aggregates","description":"Time-bucketed error counts + audit-event volume sourced from the AE SQL API. Cached 60s per (since, until, granularity) tuple. `requests` totals + `latency` are placeholders until the log helper emits per-request lines (tracked separately).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Inclusive lower bound on ts, unix epoch milliseconds. Default: now - 24h."},"required":false,"name":"since","in":"query"},{"schema":{"type":"integer","nullable":true,"minimum":0,"description":"Inclusive upper bound on ts, unix epoch milliseconds. Default: now."},"required":false,"name":"until","in":"query"},{"schema":{"type":"string","enum":["hour","day"],"default":"hour","description":"Time bucket size for the returned series. `hour` or `day`."},"required":false,"name":"granularity","in":"query"}],"responses":{"200":{"description":"Operational aggregates for the requested window.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OperationalDashboard"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"503":{"description":"Analytics Engine SQL is not configured for this env.","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/OperationalDashboard"}}}}}}},"/admin/dashboard/security":{"get":{"tags":["admin"],"summary":"Admin: security posture","description":"Aggregate security posture: admin-2fa enrollment + recent use, failed-signin counters (24h + 7d), magic-link health (7d), JWT rotation state. Sourced from D1; not cached.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Security posture snapshot.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityDashboard"}}}},"400":{"description":"Bad request","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"401":{"description":"Authentication required","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"403":{"description":"Forbidden","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"422":{"description":"Validation failed","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"429":{"description":"Rate limited","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"500":{"description":"Internal error","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}},"501":{"description":"Not implemented","content":{"application/problem+json":{"schema":{"$ref":"#/components/schemas/Problem"}}}}}}}}}