{"openapi":"3.1.0","info":{"title":"Carrier REST API","version":"1.0.0","description":"Carrier REST API. Issue one eSIM with a ConnectivityIntent (test plans never touch the network) and receive esim.issued on a signed webhook, or call any of the 52 OCS tools over HTTP. Same auth and quota as the MCP server. Build: 3f036c7300394b377430aabe611c237e4dad54ab","contact":{"name":"Carrier Support","url":"https://carrier.llc","email":"support@carrier.llc"},"license":{"name":"MIT"}},"servers":[{"url":"https://api.carrier.llc","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Clerk session JWT. Obtain from https://accounts.carrier.llc/sign-in"},"internalBearer":{"type":"http","scheme":"bearer","description":"CARRIER_INTERNAL_API_KEY. Sent by the ocs-bridge. Not a Clerk session."},"storefrontBearer":{"type":"http","scheme":"bearer","description":"CARRIER_STOREFRONT_API_KEY, required only when that secret is set on the deployment."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"string"}},"required":["error"]},"OcsError":{"type":"object","properties":{"error":{"type":"string"},"ocs_code":{"type":"integer"}},"required":["error"]},"OrgNotConnected":{"type":"object","description":"The active organization is not connected to Carrier, and the caller belongs to another organization that is. Returned instead of provisioning a stray second organization (alert #78).","properties":{"error":{"type":"string"},"error_code":{"type":"string","enum":["org_not_connected"]},"active_org":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"switch_to":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}},"connected_orgs":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}},"connect_url":{"type":"string","format":"uri"}},"required":["error","error_code","active_org","switch_to","connect_url"]},"QuotaExceeded":{"type":"object","properties":{"error":{"type":"string"},"limit":{"type":"integer"},"used":{"type":"integer"},"reset_at":{"type":"string","format":"date-time"},"upgrade_url":{"type":"string"}}},"UpgradeRequired":{"type":"object","properties":{"error":{"type":"string"},"required_tier":{"type":"string","enum":["pro","enterprise"]},"upgrade_url":{"type":"string"}}},"ConfirmTokenRequired":{"type":"object","properties":{"message":{"type":"string"},"confirm_token":{"type":"string"},"expires_in_seconds":{"type":"integer"},"route":{"type":"string"}}},"InvoicePeriod":{"type":"object","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"year":{"type":"integer"},"month":{"type":"integer","minimum":1,"maximum":12},"status":{"type":"string","enum":["open","closed","invoiced"]},"closed_at":{"type":["integer","null"]},"created_at":{"type":"integer"}}},"Invoice":{"type":"object","properties":{"id":{"type":"string"},"org_id":{"type":"string"},"period_id":{"type":"string"},"invoice_number":{"type":"string"},"status":{"type":"string","enum":["draft","sent","paid","void"]},"currency":{"type":"string","enum":["USD","EUR","GBP","CHF"]},"subtotal_cents":{"type":"integer"},"tax_cents":{"type":"integer"},"total_cents":{"type":"integer"},"stripe_connect_account_id":{"type":["string","null"]},"stripe_invoice_id":{"type":["string","null"]},"platform_fee_cents":{"type":"integer"},"recipient_name":{"type":["string","null"]},"recipient_email":{"type":["string","null"]},"notes":{"type":["string","null"]},"pdf_url":{"type":["string","null"]},"issued_at":{"type":["integer","null"]},"due_at":{"type":["integer","null"]},"paid_at":{"type":["integer","null"]},"created_at":{"type":"integer"},"updated_at":{"type":"integer"}}},"InvoiceLineItem":{"type":"object","description":"One ICCID's usage for the period. `quantity` is always 1.","properties":{"id":{"type":"string"},"invoice_id":{"type":"string"},"iccid":{"type":"string"},"description":{"type":"string"},"bytes_up":{"type":"integer"},"bytes_down":{"type":"integer"},"bytes_total":{"type":"integer"},"unit_price_cents":{"type":"integer","description":"Price per GB"},"quantity":{"type":"integer"},"amount_cents":{"type":"integer"},"currency":{"type":"string","enum":["USD","EUR","GBP","CHF"]},"network":{"type":["string","null"]},"country":{"type":["string","null"]},"created_at":{"type":"integer"}}},"BillingConfig":{"type":"object","properties":{"org_id":{"type":"string"},"currency":{"type":"string","enum":["USD","EUR","GBP","CHF"]},"billing_cycle_day":{"type":"integer"},"stripe_connect_account_id":{"type":["string","null"]},"stripe_connect_status":{"type":"string","enum":["not_connected","pending","active"]},"platform_fee_bps":{"type":"integer"},"price_per_gb_cents":{"type":"integer"},"invoice_prefix":{"type":"string"},"updated_at":{"type":"integer"}}},"StripeConnectStatus":{"type":"object","properties":{"status":{"type":"string","enum":["not_connected","pending","active"]},"account_id":{"type":["string","null"]},"charges_enabled":{"type":"boolean"},"payouts_enabled":{"type":"boolean"},"details_submitted":{"type":"boolean"},"requirements":{"type":["object","null"]},"capabilities":{"type":["object","null"]},"default_currency":{"type":"string"},"platform_fee_bps":{"type":"integer"},"payout_schedule":{"type":["object","null"]}}},"ConnectivityProductCreate":{"type":"object","required":["name","data_mb","validity_days","countries","price_cents","currency","package_template_id"],"properties":{"name":{"type":"string","maxLength":80},"data_mb":{"type":"integer","minimum":1,"description":"Allowance the operator declares, in megabytes."},"validity_days":{"type":"integer","minimum":1},"countries":{"type":"array","items":{"type":"string"},"description":"Operator-declared codes. Not a coverage lookup."},"price_cents":{"type":"integer","minimum":1,"description":"Catalogue price in minor units. Not a wallet debit."},"currency":{"type":"string","enum":["USD","EUR","GBP","CHF"]},"package_template_id":{"type":"integer","minimum":1,"description":"OCS package template the operator checked."},"account_id":{"type":"integer","description":"Pin to this account, or omit to draw from the caller at issue time."}}},"ConnectivityPlan":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"connectivity.plan"},"name":{"type":"string"},"data_mb":{"type":"integer","description":"0 when unlimited is true. Never means unlimited on its own."},"unlimited":{"type":"boolean","description":"True only when the plan is explicitly unlimited."},"validity_days":{"type":"integer"},"countries":{"type":"array","items":{"type":"string"}},"livemode":{"type":"boolean"},"price":{"description":"Catalogue price. Null on test plans. Not charged when the plan is issued.","oneOf":[{"type":"object","properties":{"amount":{"type":"integer"},"currency":{"type":"string"}},"required":["amount","currency"]},{"type":"null"}]}},"required":["id","object","name","data_mb","unlimited","validity_days","countries","livemode","price"]},"ConnectivityPlanList":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectivityPlan"}}},"required":["object","data"]},"ConnectivityIntentCreate":{"type":"object","properties":{"plan":{"type":"string","description":"test_global_1gb, test_eu_1gb, a product id (cnp_…), or a live catalogue slug. Omit to create an intent in requires_plan."},"metadata":{"type":"object","additionalProperties":{"type":"string"}}}},"ConnectivityEsim":{"type":"object","properties":{"iccid":{"type":"string"},"activation_code":{"type":["string","null"]},"qr_code":{"type":["string","null"]},"smdp_address":{"type":["string","null"]},"matching_id":{"type":["string","null"]}},"required":["iccid"]},"ConnectivityIntent":{"type":"object","properties":{"id":{"type":"string","description":"cni_…","example":"cni_0123456789abcdef0123456789abcdef"},"object":{"type":"string","const":"connectivity.intent"},"status":{"type":"string","enum":["requires_plan","processing","succeeded","failed"]},"livemode":{"type":"boolean"},"plan":{"oneOf":[{"$ref":"#/components/schemas/ConnectivityPlan"},{"type":"null"}]},"esim":{"oneOf":[{"$ref":"#/components/schemas/ConnectivityEsim"},{"type":"null"}]},"metadata":{"type":"object","additionalProperties":{"type":"string"}},"error":{"oneOf":[{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}},"required":["code","message"]},{"type":"null"}]},"created":{"type":"integer","description":"Unix seconds"}},"required":["id","object","status","livemode","metadata","created"]},"ConnectivityIntentList":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectivityIntent"}}},"required":["object","data"]},"ConnectivityWebhookEndpointCreate":{"type":"object","required":["url"],"properties":{"url":{"type":"string","description":"Absolute https URL. No userinfo."}}},"ConnectivityWebhookEndpoint":{"type":"object","properties":{"id":{"type":"string","description":"we_…"},"object":{"type":"string","const":"connectivity.webhook_endpoint"},"url":{"type":"string"},"status":{"type":"string","enum":["enabled","disabled"]},"created":{"type":"integer","description":"Unix seconds"}},"required":["id","object","url","status","created"]},"ConnectivityWebhookEndpointCreated":{"allOf":[{"$ref":"#/components/schemas/ConnectivityWebhookEndpoint"},{"type":"object","required":["secret"],"properties":{"secret":{"type":"string","description":"whsec_… Returned only on create."}}}]},"ConnectivityWebhookEndpointList":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectivityWebhookEndpoint"}}},"required":["object","data"]},"ConnectivityWebhookEndpointDeleted":{"type":"object","properties":{"id":{"type":"string"},"object":{"type":"string","const":"connectivity.webhook_endpoint"},"deleted":{"type":"boolean","const":true}},"required":["id","object","deleted"]},"ConnectivityEvent":{"type":"object","properties":{"id":{"type":"string","description":"evt_…"},"object":{"type":"string","const":"connectivity.event"},"type":{"type":"string","enum":["esim.issued","esim.first_attach","usage.threshold_reached"]},"livemode":{"type":"boolean"},"created":{"type":"integer","description":"Unix seconds"},"data":{"type":"object","additionalProperties":true}},"required":["id","object","type","livemode","created","data"]},"ConnectivityUsageRecordCreate":{"type":"object","required":["intent","quantity_mb"],"properties":{"intent":{"type":"string","description":"cni_…"},"quantity_mb":{"type":"number","exclusiveMinimum":0,"maximum":1000000}}},"ConnectivityUsageRecord":{"type":"object","properties":{"id":{"type":"string","description":"ur_…"},"object":{"type":"string","const":"connectivity.usage_record"},"intent":{"type":"string"},"quantity_mb":{"type":"number"},"livemode":{"type":"boolean"},"created":{"type":"integer","description":"Unix seconds"}},"required":["id","object","intent","quantity_mb","livemode","created"]},"ConnectivityUsageRecordList":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectivityUsageRecord"}}},"required":["object","data"]},"ConnectivityEventList":{"type":"object","properties":{"object":{"type":"string","const":"list"},"data":{"type":"array","items":{"$ref":"#/components/schemas/ConnectivityEvent"}}},"required":["object","data"]},"Health":{"type":"object","properties":{"ok":{"type":"boolean"},"version":{"type":"string"},"build_sha":{"type":"string"}},"required":["ok","version","build_sha"]}}},"paths":{"/v1/accounts":{"get":{"operationId":"list_reseller_accounts","summary":"List all reseller sub-accounts","tags":["Accounts"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/reseller":{"get":{"operationId":"get_reseller_info","summary":"Get authenticated reseller profile and balance","tags":["Reseller"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/accounts/{accountId}/esim-status":{"get":{"operationId":"esim_status_per_account","summary":"Get eSIM provisioning status counts for an account","tags":["Accounts"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/sponsors":{"get":{"operationId":"list_sponsors","summary":"List sponsor entries for the reseller","tags":["Reseller"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/steering-lists":{"get":{"operationId":"list_steering_lists","summary":"List network steering lists for the reseller","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"},"description":"Steering lists for the reseller. Empty is []."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers/{iccid}":{"get":{"operationId":"get_subscriber","summary":"Get subscriber details by ICCID","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers":{"get":{"operationId":"list_subscribers","summary":"List subscribers with optional filters","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"q","in":"query","required":false,"description":"Free-text subscriber search. A digit string starting with 89 (length 6–22) is sent as iccidPrefix. A 15-digit string that does not start with 89 is sent as imsiPrefix. Any other 6–15 digit string is sent as msisdnPrefix. q itself is never sent to OCS. A name or email is matched against the rows of an already-scoped account list.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"},"description":"Subscriber records for the scoped account, each with a resolved `currentStatus`."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"post":{"operationId":"create_subscriber","summary":"Subscriber creation is not available on the OCS","description":"Returns 501 PROVISIONING_NOT_SUPPORTED. The OCS has no createSubscriber method. Issue a free eSIM with POST /v1/subscribers/issue-from-inventory.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"responses":{"402":{"description":"Scope 'write' required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"501":{"description":"Provisioning is not supported","content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string"},"code":{"type":"string","const":"PROVISIONING_NOT_SUPPORTED"}}}}}}}}},"/v1/subscribers/{iccid}/sim-status":{"get":{"operationId":"get_sim_provider_status","summary":"Get SIM provider status for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["array","object","null"],"items":{"type":"object"},"description":"SIM provider status history (OCS getSimProviderStatus): an array, or the OCS envelope. null when OCS reports no status."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"put":{"operationId":"change_sim_status","summary":"Change SIM card status at the platform level (admin only)","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/location":{"get":{"operationId":"get_subscriber_location","summary":"Get last known location of a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers/{iccid}/bitrate":{"get":{"operationId":"hlr_get_bitrate","summary":"Get HLR bitrate limit for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["string","object","null"],"description":"HLR bitrate cap: UNLIMITED or a KB_* rate such as KB_1024 (OCS hlrGetBitrate), or the OCS envelope. null when OCS reports none."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"put":{"operationId":"hlr_set_bitrate","summary":"Set HLR bitrate limit for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/packages":{"get":{"operationId":"list_subscriber_packages","summary":"List active data packages for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"post":{"operationId":"assign_package","summary":"Assign a one-time data package to a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"required":["packageTemplateId"],"properties":{"packageTemplateId":{"type":"integer"},"startDate":{"type":"string","description":"With endDate, mapped to activePeriod.start. OCS has no startDate field. Omit both dates to activate at first use."},"endDate":{"type":"string","description":"With startDate, mapped to activePeriod.end. A bare date means 23:59:59."},"validityPeriod":{"type":"integer","minimum":1,"description":"Days from now. Cannot be combined with startDate or endDate."}},"example":{"packageTemplateId":553,"startDate":"2026-09-01","endDate":"2026-09-30"}}}}}},"delete":{"operationId":"clean_all_packages","summary":"Remove all packages from a subscriber (admin only)","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/package-templates":{"get":{"operationId":"list_package_templates","summary":"List available package templates","tags":["Packages"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"},"description":"Prepaid package templates (OCS listPrepaidPackageTemplate, unwrapped)."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"post":{"operationId":"create_package_template","summary":"Create a new package template","tags":["Packages"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"cost":{"description":"Field createPrepaidPackageTemplate accepts."},"databyte":{"description":"Field createPrepaidPackageTemplate accepts."},"deleted":{"description":"Field createPrepaidPackageTemplate accepts."},"destinationzoneid":{"description":"Field createPrepaidPackageTemplate accepts."},"esimSponsor":{"description":"Field createPrepaidPackageTemplate accepts."},"hotspotBlocked":{"description":"Field createPrepaidPackageTemplate accepts."},"locationzoneid":{"description":"Field createPrepaidPackageTemplate accepts."},"mocsecond":{"description":"Field createPrepaidPackageTemplate accepts."},"mosmsnumber":{"description":"Field createPrepaidPackageTemplate accepts."},"mtcsecond":{"description":"Field createPrepaidPackageTemplate accepts."},"mtsmsnumber":{"description":"Field createPrepaidPackageTemplate accepts."},"nbOccurrence":{"description":"Field createPrepaidPackageTemplate accepts."},"pckSubPrePaidPackagesDataSlicesTmpl":{"description":"Field createPrepaidPackageTemplate accepts."},"perioddays":{"description":"Field createPrepaidPackageTemplate accepts."},"picture":{"description":"Field createPrepaidPackageTemplate accepts."},"prepaidpackagetemplateid":{"description":"Field createPrepaidPackageTemplate accepts."},"prepaidpackagetemplatename":{"description":"Field createPrepaidPackageTemplate accepts."},"priority":{"description":"Field createPrepaidPackageTemplate accepts."},"rdbDestinationZones":{"description":"Field createPrepaidPackageTemplate accepts."},"rdbLocationZones":{"description":"Field createPrepaidPackageTemplate accepts."},"recurring":{"description":"Field createPrepaidPackageTemplate accepts."},"recurringPeriodicityFrequency":{"description":"Field createPrepaidPackageTemplate accepts."},"recurringPeriodicityType":{"description":"Field createPrepaidPackageTemplate accepts."},"reportUnitsPreviousPackage":{"description":"Field createPrepaidPackageTemplate accepts."},"reseller":{"description":"Field createPrepaidPackageTemplate accepts."},"resellerid":{"description":"Field createPrepaidPackageTemplate accepts."},"sponsors":{"description":"Field createPrepaidPackageTemplate accepts."},"throttleTillEnd":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingActive":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingErrorAction":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold1Limit":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold1Perc":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold2Limit":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold2Perc":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold3Limit":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold3Perc":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold4Limit":{"description":"Field createPrepaidPackageTemplate accepts."},"throttlingThreshold4Perc":{"description":"Field createPrepaidPackageTemplate accepts."},"uiEndAvailibilityPeriod":{"description":"Field createPrepaidPackageTemplate accepts."},"uiStartAvailablePeriod":{"description":"Field createPrepaidPackageTemplate accepts."},"uiVisible":{"description":"Field createPrepaidPackageTemplate accepts."},"userUiName":{"description":"Field createPrepaidPackageTemplate accepts."},"name":{"description":"Alias of prepaidpackagetemplatename. prepaidpackagetemplatename wins when both are sent."},"volume":{"description":"Alias of databyte. databyte wins when both are sent."},"dataLimit":{"description":"Alias of databyte. databyte wins when both are sent."},"dataBytes":{"description":"Alias of databyte. databyte wins when both are sent."},"validityDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"periodDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"locationZoneId":{"description":"Alias of locationzoneid. locationzoneid wins when both are sent."},"destinationZoneId":{"description":"Alias of destinationzoneid. destinationzoneid wins when both are sent."},"resellerId":{"description":"Alias of resellerid. resellerid wins when both are sent."}},"example":{"name":"Europe 5GB","dataLimit":5368709120,"validityDays":30,"locationZoneId":11}}}}}}},"/v1/location-zones":{"get":{"operationId":"list_location_zones","summary":"List location zones for the reseller","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"post":{"operationId":"create_location_zone","summary":"Create a new location zone","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"locationZoneName":{"type":"string","description":"Alias: name. locationZoneName wins when both are sent."},"name":{"type":"string","description":"Alias of locationZoneName."},"tadigList":{"type":"array","items":{"type":"string"},"description":"TADIG codes. Alias: tadigs. A comma-separated string is also accepted."},"tadigs":{"type":"array","items":{"type":"string"},"description":"Alias of tadigList. tadigList wins when both are sent."},"networkProfileId":{"type":"integer","minimum":1}},"example":{"locationZoneName":"Europe","tadigList":["AZER1","QWER1"],"networkProfileId":79}}}}}}},"/v1/location-zones/detailed":{"get":{"operationId":"list_detailed_location_zones","summary":"List location zones with full country/network detail","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["array","object","null"],"items":{"type":"object"},"description":"Location zones with operators (OCS listDetailedLocationZone): an array, or an envelope such as { zone: [...] }. null when OCS returns no records."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/destination-prefixes":{"get":{"operationId":"list_destination_prefixes","summary":"List destination prefixes for routing configuration","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers/{iccid}/usage":{"post":{"operationId":"subscriber_usage","summary":"Get subscriber data usage over a date range","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/network-events":{"post":{"operationId":"subscriber_network_events","summary":"Get subscriber network events over a date range","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/active-period":{"get":{"operationId":"subscriber_active_period","summary":"Get the active period for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/tariffs/{resellerId}":{"get":{"operationId":"get_tariff","summary":"Get tariff rules for a reseller","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"resellerId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/network-profiles":{"get":{"operationId":"list_network_profiles","summary":"List network profiles available to the reseller","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["array","object","null"],"items":{"type":"object"},"description":"Network profiles (OCS listNetworkProfile): an array, or the { networkProfile: [...] } envelope. null when OCS returns no records."}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers/{iccid}/balance":{"put":{"operationId":"modify_subscriber_balance","summary":"Add or set the prepaid balance for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"amount":{"type":"number","description":"Delta in major currency units. A $5 credit is 5, not 500."},"setBalance":{"type":"number","description":"Absolute balance in major currency units. Omit amount when setting."},"description":{"type":"string","maxLength":500,"description":"Ledger note forwarded to OCS. Trimmed; empty is omitted."}},"example":{"amount":5,"description":"refund"}}}}}}},"/v1/subscribers/{iccid}/status":{"put":{"operationId":"modify_subscriber_status","summary":"Activate, suspend, or deactivate a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":["string","null"],"description":"New subscriber lifecycle status. ACTIVE and INACTIVE are the documented pair. The route also accepts INVENTORY and matches these tokens case-insensitively. newStatus is an alias; status wins when both are sent. An empty status falls through to newStatus."},"newStatus":{"description":"Alias of status, used by the console (active, suspended, deactivated, inventory). status wins when both are sent. An empty status falls through to this field."}},"anyOf":[{"type":"object","required":["status"],"properties":{"status":{"type":"string","pattern":"\\S"}}},{"type":"object","required":["newStatus"],"properties":{"status":{"anyOf":[{"type":"null"},{"type":"string","pattern":"^\\s*$"}]},"newStatus":{"type":"string","pattern":"\\S"}}}],"example":{"status":"INACTIVE"}}}}}}},"/v1/subscribers/{iccid}/contact":{"put":{"operationId":"modify_subscriber_contact_info","summary":"Update subscriber contact information","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"name":{"type":"string"},"mail":{"type":"string","description":"Email. Alias: email."},"phone":{"type":"string","description":"Alias: phoneNumber."},"company":{"type":"string"},"email":{"type":"string","description":"Alias of mail. mail wins when both are sent."},"phoneNumber":{"type":"string","description":"Alias of phone. phone wins when both are sent."},"firstName":{"type":"string","description":"Joined with lastName into name when name is omitted."},"lastName":{"type":"string","description":"Joined with firstName into name when name is omitted."}},"example":{"name":"Ada Lovelace","mail":"ada@example.com","phone":"+447000000001"}}}}}}},"/v1/subscribers/{iccid}/traffic-restrictions":{"put":{"operationId":"set_subscriber_traffic_restrictions","summary":"Set data/voice/SMS traffic restrictions for a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/steering-list":{"put":{"operationId":"modify_subscriber_steering_list","summary":"Assign a steering list to a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/accounts/{accountId}/move-subscribers":{"post":{"operationId":"move_subscriber_range_to_account","summary":"Move a subscriber range to a different account","tags":["Accounts"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"srcAccountId":{"type":"integer","description":"Source account. Alias: fromAccountId. Path is used as source when destAccount is in the body."},"destAccount":{"type":"integer","description":"Destination account. Path is used as destination when this is omitted."},"rangeType":{"type":"string","enum":["IMSI","ICCID"],"description":"Identifier kind for rangeStart/rangeEnd. Defaults to ICCID when iccidStart/iccidEnd are sent."},"rangeStart":{"type":"string","description":"Inclusive start. Alias: iccidStart."},"rangeEnd":{"type":"string","description":"Inclusive end. Alias: iccidEnd."},"fromAccountId":{"type":"integer","description":"Alias of srcAccountId."},"iccidStart":{"type":"string","description":"Alias of rangeStart; implies rangeType=ICCID."},"iccidEnd":{"type":"string","description":"Alias of rangeEnd; implies rangeType=ICCID."}},"example":{"destAccount":6177,"rangeType":"ICCID","rangeStart":"8948010000000697656","rangeEnd":"8948010000000697656"}}}}}}},"/v1/subscribers/{iccid}/packages/recurring":{"post":{"operationId":"assign_recurring_package","summary":"Assign a recurring data package to a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/packages/{packageId}/limits":{"put":{"operationId":"modify_package_limits","summary":"Modify data limits for an assigned package","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/packages/{packageId}/expiry":{"put":{"operationId":"modify_package_expiry","summary":"Modify the expiry date of an assigned package","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/packages/{packageId}/status":{"put":{"operationId":"modify_package_status","summary":"Pause or resume an assigned package","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","pattern":"^\\s*(?:[Aa][Cc][Tt][Ii][Vv][Ee]|[Pp][Aa][Uu][Ss][Ee][Dd]|[Ii][Nn][Aa][Cc][Tt][Ii][Vv][Ee])\\s*$","description":"Package state. Parsing is case-insensitive. active keeps the package usable. paused and inactive deactivate it without deleting it."}},"example":{"status":"INACTIVE"}}}}}}},"/v1/subscribers/{iccid}/packages/{packageId}/recurring-status":{"put":{"operationId":"stop_resume_recurring_package","summary":"Stop or resume a recurring package subscription","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/accounts/{accountId}/balance":{"put":{"operationId":"modify_account_balance","summary":"Modify account-level balance (admin only)","tags":["Accounts"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"accountId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/subscribers/{iccid}/packages/{packageId}":{"delete":{"operationId":"delete_subscriber_package","summary":"Delete a subscriber package (admin only)","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/package-templates/{templateId}/core":{"put":{"operationId":"modify_template_core","summary":"Modify core settings of a package template (admin only)","tags":["Packages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"cost":{"description":"Field modifyPPTCore accepts."},"databyte":{"description":"Field modifyPPTCore accepts."},"deleted":{"description":"Field modifyPPTCore accepts."},"destinationzoneid":{"description":"Field modifyPPTCore accepts."},"esimSponsor":{"description":"Field modifyPPTCore accepts."},"hotspotBlocked":{"description":"Field modifyPPTCore accepts."},"locationzoneid":{"description":"Field modifyPPTCore accepts."},"mocsecond":{"description":"Field modifyPPTCore accepts."},"mosmsnumber":{"description":"Field modifyPPTCore accepts."},"mtcsecond":{"description":"Field modifyPPTCore accepts."},"mtsmsnumber":{"description":"Field modifyPPTCore accepts."},"nbOccurrence":{"description":"Field modifyPPTCore accepts."},"pckSubPrePaidPackagesDataSlicesTmpl":{"description":"Field modifyPPTCore accepts."},"perioddays":{"description":"Field modifyPPTCore accepts."},"picture":{"description":"Field modifyPPTCore accepts."},"prepaidpackagetemplateid":{"description":"Field modifyPPTCore accepts."},"prepaidpackagetemplatename":{"description":"Field modifyPPTCore accepts."},"priority":{"description":"Field modifyPPTCore accepts."},"rdbDestinationZones":{"description":"Field modifyPPTCore accepts."},"rdbLocationZones":{"description":"Field modifyPPTCore accepts."},"recurring":{"description":"Field modifyPPTCore accepts."},"recurringPeriodicityFrequency":{"description":"Field modifyPPTCore accepts."},"recurringPeriodicityType":{"description":"Field modifyPPTCore accepts."},"reportUnitsPreviousPackage":{"description":"Field modifyPPTCore accepts."},"reseller":{"description":"Field modifyPPTCore accepts."},"resellerid":{"description":"Field modifyPPTCore accepts."},"sponsors":{"description":"Field modifyPPTCore accepts."},"throttleTillEnd":{"description":"Field modifyPPTCore accepts."},"throttlingActive":{"description":"Field modifyPPTCore accepts."},"throttlingErrorAction":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold1Limit":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold1Perc":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold2Limit":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold2Perc":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold3Limit":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold3Perc":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold4Limit":{"description":"Field modifyPPTCore accepts."},"throttlingThreshold4Perc":{"description":"Field modifyPPTCore accepts."},"uiEndAvailibilityPeriod":{"description":"Field modifyPPTCore accepts."},"uiStartAvailablePeriod":{"description":"Field modifyPPTCore accepts."},"uiVisible":{"description":"Field modifyPPTCore accepts."},"userUiName":{"description":"Field modifyPPTCore accepts."},"changeSponsor":{"description":"Field modifyPPTCore accepts."},"name":{"description":"Alias of prepaidpackagetemplatename. prepaidpackagetemplatename wins when both are sent."},"volume":{"description":"Alias of databyte. databyte wins when both are sent."},"dataLimit":{"description":"Alias of databyte. databyte wins when both are sent."},"dataBytes":{"description":"Alias of databyte. databyte wins when both are sent."},"validityDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"periodDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"locationZoneId":{"description":"Alias of locationzoneid. locationzoneid wins when both are sent."},"destinationZoneId":{"description":"Alias of destinationzoneid. destinationzoneid wins when both are sent."},"resellerId":{"description":"Alias of resellerid. resellerid wins when both are sent."},"periodicity":{"description":"Alias of recurringPeriodicityType. recurringPeriodicityType wins when both are sent."},"occurrences":{"description":"Alias of nbOccurrence. nbOccurrence wins when both are sent."},"firstThresholdPercent":{"description":"Alias of throttlingThreshold1Perc. throttlingThreshold1Perc wins when both are sent."},"firstThresholdLimitKbps":{"description":"Alias of throttlingThreshold1Limit. throttlingThreshold1Limit wins when both are sent."},"errorAction":{"description":"Alias of throttlingErrorAction. throttlingErrorAction wins when both are sent."}},"example":{"name":"Europe 5GB","dataLimit":5368709120}}}}}}},"/v1/package-templates/{templateId}/recurring":{"put":{"operationId":"modify_template_recurring","summary":"Modify recurring settings of a package template (admin only)","tags":["Packages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"cost":{"description":"Field modifyPPTRecurring accepts."},"databyte":{"description":"Field modifyPPTRecurring accepts."},"deleted":{"description":"Field modifyPPTRecurring accepts."},"destinationzoneid":{"description":"Field modifyPPTRecurring accepts."},"esimSponsor":{"description":"Field modifyPPTRecurring accepts."},"hotspotBlocked":{"description":"Field modifyPPTRecurring accepts."},"locationzoneid":{"description":"Field modifyPPTRecurring accepts."},"mocsecond":{"description":"Field modifyPPTRecurring accepts."},"mosmsnumber":{"description":"Field modifyPPTRecurring accepts."},"mtcsecond":{"description":"Field modifyPPTRecurring accepts."},"mtsmsnumber":{"description":"Field modifyPPTRecurring accepts."},"nbOccurrence":{"description":"Field modifyPPTRecurring accepts."},"pckSubPrePaidPackagesDataSlicesTmpl":{"description":"Field modifyPPTRecurring accepts."},"perioddays":{"description":"Field modifyPPTRecurring accepts."},"picture":{"description":"Field modifyPPTRecurring accepts."},"prepaidpackagetemplateid":{"description":"Field modifyPPTRecurring accepts."},"prepaidpackagetemplatename":{"description":"Field modifyPPTRecurring accepts."},"priority":{"description":"Field modifyPPTRecurring accepts."},"rdbDestinationZones":{"description":"Field modifyPPTRecurring accepts."},"rdbLocationZones":{"description":"Field modifyPPTRecurring accepts."},"recurring":{"description":"Field modifyPPTRecurring accepts."},"recurringPeriodicityFrequency":{"description":"Field modifyPPTRecurring accepts."},"recurringPeriodicityType":{"description":"Field modifyPPTRecurring accepts."},"reportUnitsPreviousPackage":{"description":"Field modifyPPTRecurring accepts."},"reseller":{"description":"Field modifyPPTRecurring accepts."},"resellerid":{"description":"Field modifyPPTRecurring accepts."},"sponsors":{"description":"Field modifyPPTRecurring accepts."},"throttleTillEnd":{"description":"Field modifyPPTRecurring accepts."},"throttlingActive":{"description":"Field modifyPPTRecurring accepts."},"throttlingErrorAction":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold1Limit":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold1Perc":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold2Limit":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold2Perc":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold3Limit":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold3Perc":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold4Limit":{"description":"Field modifyPPTRecurring accepts."},"throttlingThreshold4Perc":{"description":"Field modifyPPTRecurring accepts."},"uiEndAvailibilityPeriod":{"description":"Field modifyPPTRecurring accepts."},"uiStartAvailablePeriod":{"description":"Field modifyPPTRecurring accepts."},"uiVisible":{"description":"Field modifyPPTRecurring accepts."},"userUiName":{"description":"Field modifyPPTRecurring accepts."},"name":{"description":"Alias of prepaidpackagetemplatename. prepaidpackagetemplatename wins when both are sent."},"volume":{"description":"Alias of databyte. databyte wins when both are sent."},"dataLimit":{"description":"Alias of databyte. databyte wins when both are sent."},"dataBytes":{"description":"Alias of databyte. databyte wins when both are sent."},"validityDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"periodDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"locationZoneId":{"description":"Alias of locationzoneid. locationzoneid wins when both are sent."},"destinationZoneId":{"description":"Alias of destinationzoneid. destinationzoneid wins when both are sent."},"resellerId":{"description":"Alias of resellerid. resellerid wins when both are sent."},"periodicity":{"description":"Alias of recurringPeriodicityType. recurringPeriodicityType wins when both are sent."},"occurrences":{"description":"Alias of nbOccurrence. nbOccurrence wins when both are sent."},"firstThresholdPercent":{"description":"Alias of throttlingThreshold1Perc. throttlingThreshold1Perc wins when both are sent."},"firstThresholdLimitKbps":{"description":"Alias of throttlingThreshold1Limit. throttlingThreshold1Limit wins when both are sent."},"errorAction":{"description":"Alias of throttlingErrorAction. throttlingErrorAction wins when both are sent."}},"example":{"periodicity":"monthly","occurrences":12}}}}}}},"/v1/package-templates/{templateId}/throttling":{"put":{"operationId":"modify_template_throttling","summary":"Modify throttling settings of a package template (admin only)","tags":["Packages"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"templateId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":false,"properties":{"cost":{"description":"Field modifyPPTThrottling accepts."},"databyte":{"description":"Field modifyPPTThrottling accepts."},"deleted":{"description":"Field modifyPPTThrottling accepts."},"destinationzoneid":{"description":"Field modifyPPTThrottling accepts."},"esimSponsor":{"description":"Field modifyPPTThrottling accepts."},"hotspotBlocked":{"description":"Field modifyPPTThrottling accepts."},"locationzoneid":{"description":"Field modifyPPTThrottling accepts."},"mocsecond":{"description":"Field modifyPPTThrottling accepts."},"mosmsnumber":{"description":"Field modifyPPTThrottling accepts."},"mtcsecond":{"description":"Field modifyPPTThrottling accepts."},"mtsmsnumber":{"description":"Field modifyPPTThrottling accepts."},"nbOccurrence":{"description":"Field modifyPPTThrottling accepts."},"pckSubPrePaidPackagesDataSlicesTmpl":{"description":"Field modifyPPTThrottling accepts."},"perioddays":{"description":"Field modifyPPTThrottling accepts."},"picture":{"description":"Field modifyPPTThrottling accepts."},"prepaidpackagetemplateid":{"description":"Field modifyPPTThrottling accepts."},"prepaidpackagetemplatename":{"description":"Field modifyPPTThrottling accepts."},"priority":{"description":"Field modifyPPTThrottling accepts."},"rdbDestinationZones":{"description":"Field modifyPPTThrottling accepts."},"rdbLocationZones":{"description":"Field modifyPPTThrottling accepts."},"recurring":{"description":"Field modifyPPTThrottling accepts."},"recurringPeriodicityFrequency":{"description":"Field modifyPPTThrottling accepts."},"recurringPeriodicityType":{"description":"Field modifyPPTThrottling accepts."},"reportUnitsPreviousPackage":{"description":"Field modifyPPTThrottling accepts."},"reseller":{"description":"Field modifyPPTThrottling accepts."},"resellerid":{"description":"Field modifyPPTThrottling accepts."},"sponsors":{"description":"Field modifyPPTThrottling accepts."},"throttleTillEnd":{"description":"Field modifyPPTThrottling accepts."},"throttlingActive":{"description":"Field modifyPPTThrottling accepts."},"throttlingErrorAction":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold1Limit":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold1Perc":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold2Limit":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold2Perc":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold3Limit":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold3Perc":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold4Limit":{"description":"Field modifyPPTThrottling accepts."},"throttlingThreshold4Perc":{"description":"Field modifyPPTThrottling accepts."},"uiEndAvailibilityPeriod":{"description":"Field modifyPPTThrottling accepts."},"uiStartAvailablePeriod":{"description":"Field modifyPPTThrottling accepts."},"uiVisible":{"description":"Field modifyPPTThrottling accepts."},"userUiName":{"description":"Field modifyPPTThrottling accepts."},"name":{"description":"Alias of prepaidpackagetemplatename. prepaidpackagetemplatename wins when both are sent."},"volume":{"description":"Alias of databyte. databyte wins when both are sent."},"dataLimit":{"description":"Alias of databyte. databyte wins when both are sent."},"dataBytes":{"description":"Alias of databyte. databyte wins when both are sent."},"validityDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"periodDays":{"description":"Alias of perioddays. perioddays wins when both are sent."},"locationZoneId":{"description":"Alias of locationzoneid. locationzoneid wins when both are sent."},"destinationZoneId":{"description":"Alias of destinationzoneid. destinationzoneid wins when both are sent."},"resellerId":{"description":"Alias of resellerid. resellerid wins when both are sent."},"periodicity":{"description":"Alias of recurringPeriodicityType. recurringPeriodicityType wins when both are sent."},"occurrences":{"description":"Alias of nbOccurrence. nbOccurrence wins when both are sent."},"firstThresholdPercent":{"description":"Alias of throttlingThreshold1Perc. throttlingThreshold1Perc wins when both are sent."},"firstThresholdLimitKbps":{"description":"Alias of throttlingThreshold1Limit. throttlingThreshold1Limit wins when both are sent."},"errorAction":{"description":"Alias of throttlingErrorAction. throttlingErrorAction wins when both are sent."}},"example":{"throttlingActive":true,"firstThresholdPercent":80,"firstThresholdLimitKbps":1024}}}}}}},"/v1/subscribers/{iccid}/sms":{"post":{"operationId":"send_sms","summary":"Send an MT SMS to a subscriber (admin only)","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}}}},"/v1/intelligence/fleet-health":{"post":{"operationId":"fleet_health","summary":"Aggregate fleet health: active/suspended/inactive counts, low balance alerts","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/churn-risk":{"post":{"operationId":"churn_risk","summary":"Identify subscribers at churn risk based on usage patterns","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/audit-network-coverage":{"post":{"operationId":"audit_network_coverage","summary":"Audit network coverage against location zones","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/diagnose-subscriber":{"post":{"operationId":"diagnose_subscriber","summary":"Deep-dive diagnostic for a single subscriber","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/detect-usage-anomalies":{"post":{"operationId":"detect_usage_anomalies","summary":"Detect unusual usage spikes or drops across the fleet","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/optimize-package":{"post":{"operationId":"optimize_package","summary":"Recommend optimal package based on subscriber usage history","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/marketing-intelligence":{"post":{"operationId":"marketing_intelligence","summary":"Segment subscribers for targeted campaigns","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/high-cost-subscribers":{"post":{"operationId":"high_cost_subscribers","summary":"Identify highest-cost subscribers for cost optimization","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}},"get":{"operationId":"high_cost_subscribers_method_guard","summary":"GET is not supported. Use POST.","description":"Answers 405. The query is POST /v1/intelligence/high-cost-subscribers with a JSON body of start, end, and limit. A threshold query parameter is not accepted.","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"responses":{"405":{"description":"Use POST","content":{"application/json":{"schema":{"type":"object","required":["error","detail"],"properties":{"error":{"type":"string"},"detail":{"type":"string"}}}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/intelligence/detect-country-entry":{"post":{"operationId":"detect_country_entry","summary":"Resolve a subscriber's current country from networkInfo.lastMcc and diff it against expectedCountry","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"subscriber":{"iccid":"89001012012341234512"},"expectedCountry":"NL"}}}}},"responses":{"200":{"description":"Intelligence result","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded"},"502":{"description":"OCS upstream error"}}}},"/v1/intelligence/schedules":{"get":{"operationId":"list_intelligence_schedules","summary":"List scheduled intelligence reports for the caller's organization","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Schedules. Webhook secrets are omitted."},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}},"post":{"operationId":"create_intelligence_schedule","summary":"Schedule one of the 8 composites. Returns the webhook secret once.","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["composite","cadence"],"properties":{"composite":{"type":"string"},"cadence":{"type":"string","enum":["daily","weekly"]},"webhook_url":{"type":"string"},"brand_name":{"type":"string"},"accent":{"type":"string"},"params":{"type":"object"}}}}}},"responses":{"201":{"description":"Schedule created"},"400":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/intelligence/schedules/{id}":{"delete":{"operationId":"delete_intelligence_schedule","summary":"Delete a scheduled report and its share link","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted"},"404":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/intelligence/schedules/{id}/run":{"post":{"operationId":"run_intelligence_schedule","summary":"Run a schedule now. Does not move the next cron boundary.","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Report stored"},"404":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/intelligence/schedules/{id}/report":{"get":{"operationId":"get_intelligence_schedule_report","summary":"Latest report for a schedule, unredacted, for the owning organization","tags":["Intelligence"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Latest report"},"404":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/intelligence/share/{token}":{"get":{"operationId":"get_intelligence_share","summary":"Public branded report. Subscriber identifiers are redacted. ?format=html returns a page.","tags":["Intelligence"],"security":[],"parameters":[{"name":"token","in":"path","required":true,"schema":{"type":"string"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","enum":["html"]}}],"responses":{"200":{"description":"Redacted report"},"404":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string"}}}}}}}}},"/v1/operator-billing/connect/begin":{"post":{"operationId":"operator_billing_connect_begin","summary":"Initiate Stripe Connect onboarding (free-tier; Clerk auth only)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"return_url":"https://console.carrier.llc/billing","refresh_url":"https://console.carrier.llc/billing","account_type":"express"}}}}},"responses":{"200":{"description":"Stripe AccountLink URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"500":{"description":"Stripe or DB error"}}}},"/v1/operator-billing/connect/oauth/begin":{"post":{"operationId":"operator_billing_connect_oauth_begin","summary":"Start Standard Connect OAuth (existing verified Stripe, no second KYC)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"return_url":{"type":"string"}},"example":{"return_url":"https://app.carrier.llc/operator-billing"}}}}},"responses":{"200":{"description":"Stripe OAuth authorize URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"401":{"description":"Unauthorized"},"503":{"description":"STRIPE_CONNECT_CLIENT_ID missing"}}}},"/v1/operator-billing/connect/oauth/complete":{"post":{"operationId":"operator_billing_connect_oauth_complete","summary":"Finish Standard Connect OAuth and attach stripe_user_id","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["code","state"],"properties":{"code":{"type":"string"},"state":{"type":"string"}}}}}},"responses":{"200":{"description":"Connected account id","content":{"application/json":{"schema":{"type":"object","properties":{"account_id":{"type":"string"},"kyc_reused":{"type":"boolean"}}}}}},"400":{"description":"Invalid or expired OAuth state"},"401":{"description":"Unauthorized"},"502":{"description":"Stripe OAuth token failed"}}}},"/v1/operator-billing/connect/status":{"get":{"operationId":"operator_billing_connect_status","summary":"Get Stripe Connect account status and requirements","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Connect status","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"500":{"description":"Stripe or DB error"}}}},"/v1/operator-billing/connect/dashboard-link":{"post":{"operationId":"operator_billing_connect_dashboard_link","summary":"Generate Stripe Express Dashboard login link","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Dashboard URL","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"500":{"description":"Stripe or DB error"}}}},"/v1/operator-billing/payouts":{"get":{"operationId":"operator_billing_list_payouts","summary":"List payout history (paginated)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Payout list","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/payouts/manual":{"post":{"operationId":"operator_billing_create_manual_payout","summary":"Create a manual payout to the connected bank account","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"amount_cents":10000,"currency":"usd","description":"Manual payout"}}}}},"responses":{"201":{"description":"Payout created","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/payouts/schedule":{"get":{"operationId":"operator_billing_get_payout_schedule","summary":"Get current payout schedule","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Payout schedule","content":{"application/json":{"schema":{"type":"object","properties":{"interval":{"type":"string"},"delay_days":{"type":"integer"}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}},"patch":{"operationId":"operator_billing_update_payout_schedule","summary":"Update payout schedule (daily / weekly / monthly)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"interval":"weekly","delay_days":2,"weekly_anchor":"monday"}}}}},"responses":{"200":{"description":"Updated schedule"},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/fees":{"get":{"operationId":"operator_billing_list_fees","summary":"List Carrier platform fees earned (admin scope required)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Fee list","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized — admin scope required"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/charges":{"get":{"operationId":"operator_billing_list_charges","summary":"List storefront payments (charges) on this operator's connected Stripe account","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20,"minimum":1,"maximum":100}},{"name":"starting_after","in":"query","schema":{"type":"string"},"description":"Charge id (ch_ or py_) to page after."}],"responses":{"200":{"description":"Charge list: { charges: [...], has_more }","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Stripe lookup failed"}}}},"/v1/operator-billing/balance":{"get":{"operationId":"operator_billing_get_balance","summary":"Available and pending balance on this operator's connected Stripe account","description":"In Stripe test mode the org sells on Carrier's shared platform test account, so no per-org balance exists: the response has stripe_mode \"test\", empty available/pending and a note.","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"{ account_id, available: [{ amount, currency }], pending: [...], stripe_mode?, note? }","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Stripe lookup failed"}}}},"/v1/operator-billing/refunds":{"get":{"operationId":"operator_billing_list_refunds","summary":"List refunds issued by this operator","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}}],"responses":{"200":{"description":"Refund list","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}},"post":{"operationId":"operator_billing_create_refund","summary":"Issue a refund against a Stripe charge","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"charge_id":"ch_xxx","amount":5000,"reason":"requested_by_customer"}}}}},"responses":{"201":{"description":"Refund created","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"No connected Stripe account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/disputes":{"get":{"operationId":"operator_billing_list_disputes","summary":"List active and historical disputes","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"status","in":"query","schema":{"type":"string"},"description":"Filter by dispute status, e.g. needs_response or under_review."}],"responses":{"200":{"description":"Dispute list","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/disputes/{id}/evidence":{"post":{"operationId":"operator_billing_submit_dispute_evidence","summary":"Submit evidence for a dispute","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Evidence submitted","content":{"application/json":{"schema":{"type":"object","properties":{"submitted":{"type":"boolean"}}}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized"},"404":{"description":"Dispute not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/fraud/reviews":{"get":{"operationId":"operator_billing_list_fraud_reviews","summary":"List Radar review queue","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","schema":{"type":"integer","default":20}},{"name":"offset","in":"query","schema":{"type":"integer","default":0}},{"name":"open","in":"query","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"Review list","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/fraud/reviews/{id}/approve":{"post":{"operationId":"operator_billing_approve_fraud_review","summary":"Approve a Radar review (admin scope required)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Review approved","content":{"application/json":{"schema":{"type":"object","properties":{"approved":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized — admin scope required"},"404":{"description":"Review not found"},"409":{"description":"Review already closed. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}}}}},"/v1/operator-billing/fraud/reviews/{id}/decline":{"post":{"operationId":"operator_billing_decline_fraud_review","summary":"Not supported: Stripe has no Radar review decline (admin scope required)","description":"Always answers 501 and sends nothing to Stripe. Refund the charge with POST /v1/operator-billing/refunds (Carrier). If the payment was authorized but not captured, cancel its PaymentIntent in Stripe (Stripe API POST /v1/payment_intents/:id/cancel); Carrier has no route for that. Either closes the review. See https://docs.stripe.com/radar/reviews.","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"401":{"description":"Unauthorized — admin scope required"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"501":{"description":"Stripe has no review decline endpoint","content":{"application/json":{"schema":{"type":"object","required":["error","code","detail","docs"],"properties":{"error":{"type":"string"},"code":{"type":"string","enum":["review_decline_not_supported"]},"detail":{"type":"string"},"docs":{"type":"string"}}}}}}}}},"/v1/operator-billing/fraud/value-lists":{"get":{"operationId":"operator_billing_list_value_lists","summary":"List Radar block/allow value lists","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Value lists","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/fraud/value-lists/items":{"post":{"operationId":"operator_billing_add_value_list_item","summary":"Add an item to a Radar block/allow list (admin scope required)","tags":["Operator Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"value_list_id":"rsl_xxx","value":"4242424242424242"}}}}},"responses":{"201":{"description":"Item added","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error"},"401":{"description":"Unauthorized — admin scope required"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/affiliates/me":{"get":{"operationId":"affiliates_me_get","summary":"Get this org's affiliate link, referral count, earnings and payout status","tags":["Affiliates"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Affiliate profile","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"ref_code":{"type":"string","description":"8 characters, no 0/O/1/I"},"link":{"type":"string"},"status":{"type":"string","enum":["active","suspended"]},"referrals":{"type":"integer"},"pending_cents":{"type":"integer","description":"EUR cents earned and not yet paid out"},"paid_cents":{"type":"integer","description":"EUR cents already paid out"},"payouts_enabled":{"type":"boolean","description":"Stripe Connect account can receive payouts"}}}}}}}},"401":{"description":"Unauthorized"},"404":{"description":"Not an affiliate yet"},"503":{"description":"Billing database not configured"}}},"post":{"operationId":"affiliates_me_create","summary":"Join the affiliate programme (idempotent: returns the existing code)","tags":["Affiliates"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Already an affiliate","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"ref_code":{"type":"string"},"link":{"type":"string"}}}}}}}},"201":{"description":"Joined","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"ref_code":{"type":"string"},"link":{"type":"string"}}}}}}}},"401":{"description":"Unauthorized"},"500":{"description":"Could not allocate a referral code"},"503":{"description":"Billing database not configured"}}}},"/v1/affiliates/me/commissions":{"get":{"operationId":"affiliates_me_commissions_list","summary":"List commissions for this org, newest period first","tags":["Affiliates"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Max rows to return (1-200, default 50)"}],"responses":{"200":{"description":"List of commissions","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"period":{"type":"string","example":"2026-08"},"referred_org_id":{"type":"string"},"base_cents":{"type":"integer"},"commission_bps":{"type":"integer"},"commission_cents":{"type":"integer"},"status":{"type":"string","enum":["pending","paid","failed"]},"unmeasured_rows":{"type":"integer"}}}}}}}}},"401":{"description":"Unauthorized"},"503":{"description":"Billing database not configured"}}}},"/v1/affiliates/link":{"post":{"operationId":"affiliates_link","summary":"Attach a referral code to an organization created less than 30 minutes ago (browser sign-up only)","tags":["Affiliates"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["ref"],"properties":{"ref":{"type":"string","maxLength":16}},"example":{"ref":"ABCD2345"}}}}},"responses":{"200":{"description":"Linked, or not linked with a reason (unknown_code, self_referral, already_linked)","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"linked":{"type":"boolean"},"reason":{"type":"string","enum":["unknown_code","self_referral","already_linked"]}}}}}}}},"400":{"description":"ref is required"},"401":{"description":"Unauthorized"},"409":{"description":"too_late: the organization is older than 30 minutes, or is a personal account"},"503":{"description":"Billing database not configured"}}}},"/v1/operator-billing/identity/status":{"get":{"operationId":"operator_identity_status","summary":"Get Stripe Identity KYC verification status for this operator","tags":["Identity"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Identity status","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/identity/sessions":{"post":{"operationId":"operator_identity_create_session","summary":"Record a new Stripe Identity verification session","tags":["Identity"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"session_id":"vs_xxx","status":"requires_input"}}}}},"responses":{"200":{"description":"Session recorded","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"session_id":{"type":"string"}}}}}},"400":{"description":"Missing session_id"},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/operator-billing/identity/sessions/{id}":{"patch":{"operationId":"operator_identity_update_session","summary":"Update a Stripe Identity session status (internal API key only)","tags":["Identity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"status":"verified","verified_at":1715000000000}}}}},"responses":{"200":{"description":"Session updated","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized — internal API key required"}}}},"/v1/operator-billing/promotions":{"get":{"operationId":"operator_list_promotions","summary":"List promotions (coupons/promo codes) for this operator","tags":["Promotions"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Promotion list","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}},"post":{"operationId":"operator_create_promotion","summary":"Persist a new promotion record (Stripe coupon already created by console)","tags":["Promotions"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"id":"promo_xxx","coupon_id":"coupon_xxx","code":"LAUNCH20","discount_type":"percent","discount_value":20,"currency":null,"duration":"once"}}}}},"responses":{"200":{"description":"Promotion created","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"id":{"type":"string"}}}}}},"400":{"description":"Missing required fields"},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/signup":{"post":{"operationId":"signup_start","summary":"Create a Carrier account and send the email verification code","description":"Headless sign-up for the CLI. Creates a Clerk sign-up and sends a verification code to the address given. Unauthenticated by necessity — the caller has no credential yet — and rate limited by client IP and email address. Returns a short-lived client token that POST /v1/signup/verify needs.","tags":["Sign-up"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email_address","password","first_name","last_name"],"properties":{"email_address":{"type":"string","format":"email","maxLength":254},"password":{"type":"string","maxLength":512},"first_name":{"type":"string","maxLength":128},"last_name":{"type":"string","maxLength":128},"legal_accepted":{"type":"boolean","description":"Send true only when the instance requires consent — read legal_consent_enabled from Clerk's /v1/environment first."}},"example":{"email_address":"ada@example.com","password":"correct horse battery staple","first_name":"Ada","last_name":"Lovelace"}}}}},"responses":{"201":{"description":"Sign-up created; verification code sent","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"sign_up_id":{"type":"string"},"client_token":{"type":"string","description":"Pass back to /v1/signup/verify. Not a session token."},"status":{"type":"string"},"email_address":{"type":"string"},"verification_required":{"type":"boolean"}}}}}}}},"400":{"description":"Invalid body, or Clerk rejected the details (message forwarded)"},"429":{"description":"Sign-up rate limit reached for this email address or network"},"502":{"description":"Clerk returned no client token"},"503":{"description":"Sign-up is not configured on this deployment"}}}},"/v1/signup/verify":{"post":{"operationId":"signup_verify","summary":"Submit the emailed code and create the organization","description":"Completes the sign-up started by POST /v1/signup and creates the caller's organization. A wrong code answers 400 with Clerk's form_code_incorrect and can be retried. Sign in normally afterwards — this route returns no session credential.","tags":["Sign-up"],"security":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["sign_up_id","client_token","code"],"properties":{"sign_up_id":{"type":"string","maxLength":128},"client_token":{"type":"string","maxLength":4096},"code":{"type":"string","pattern":"^[0-9]{4,8}$"},"organization_name":{"type":"string","maxLength":128},"ref":{"type":"string","maxLength":16,"description":"Optional affiliate referral code. Links the new organization to the referrer at sign-up. A bad or unknown code never fails the sign-up."}},"example":{"sign_up_id":"sua_123","client_token":"eyJ…","code":"123456"}}}}},"responses":{"201":{"description":"Account verified and organization created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"status":{"type":"string"},"user_id":{"type":"string"},"email_address":{"type":"string"},"organization_id":{"type":"string"},"organization_name":{"type":"string"},"session_id":{"type":"string","nullable":true}}}}}}}},"400":{"description":"Invalid body, wrong code, or sign-up not complete"},"429":{"description":"Sign-up rate limit reached for this email address or network"},"502":{"description":"Account created but the organization was not"},"503":{"description":"Sign-up is not configured on this deployment"}}}},"/v1/api-keys":{"post":{"operationId":"create_api_key","summary":"Mint an ak_ API key for this organization (secret returned once)","description":"Creates a Clerk API key scoped to the caller's organization, or to the caller when there is no org context. The secret is present only in this response and cannot be retrieved again. Carrier resolves read/write/admin from tier and org membership, so the key carries no caller-supplied scopes.","tags":["API Keys"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":64,"description":"Label for the key"},"description":{"type":"string","maxLength":256},"secondsUntilExpiration":{"type":"integer","minimum":60,"maximum":31536000,"description":"Omit for a key that never expires"}},"example":{"name":"ci-deploy","description":"GitHub Actions","secondsUntilExpiration":2592000}}}}},"responses":{"201":{"description":"API key created","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"subject":{"type":"string"},"description":{"type":"string","nullable":true},"secret":{"type":"string","description":"Shown once — store it now"},"secret_shown_once":{"type":"boolean"},"expiration":{"type":"integer","nullable":true},"created_at":{"type":"integer"}}}}}}}},"400":{"description":"Invalid body, or no Clerk subject on this credential"},"401":{"description":"Unauthorized"},"402":{"description":"Write scope required"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Clerk rejected the request, or returned no secret"},"503":{"description":"Clerk secret key not configured"}}}},"/v1/onboarding":{"get":{"operationId":"get_onboarding_state","summary":"Read this org's onboarding progress","description":"Returns the same state the console onboarding UI renders, so a terminal can resume where a browser left off. Available before an OCS token is connected.","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Current onboarding state","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"The `onboarding:<org>` record after the step","additionalProperties":true}}}}}},"401":{"description":"Unauthorized"}}}},"/v1/onboarding/org":{"post":{"operationId":"onboarding_save_org","summary":"Save operator details (step 1)","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","maxLength":128},"website":{"type":"string","maxLength":256},"country":{"type":"string","maxLength":256},"operatorType":{"type":"string","maxLength":256}},"example":{"name":"Acme MVNO","country":"NL","operatorType":"mvno"}}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"The `onboarding:<org>` record after the step","additionalProperties":true}}}}}},"400":{"description":"Invalid body"},"401":{"description":"Unauthorized"}}}},"/v1/onboarding/ocs-connect":{"post":{"operationId":"onboarding_connect_ocs_token","summary":"Connect a BYO eSIMVault token (step 2)","description":"Verifies the token against OCS `getResellerInfo`, then stores it AES-256-GCM encrypted as `esimvault_token_enc`. The token is never returned. Connecting a token switches the org to BYO mode and clears any managed sub-account.","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["token"],"properties":{"token":{"type":"string","maxLength":512,"description":"eSIMVault API token"}}}}}},"responses":{"200":{"description":"Token verified and stored","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"account_mode":{"type":"string","enum":["byo"]},"reseller_name":{"type":"string"},"reseller_id":{"type":"string"}}}}}}}},"400":{"description":"Invalid body"},"401":{"description":"Unauthorized"},"502":{"description":"OCS rejected the token"}}}},"/v1/onboarding/managed-account":{"post":{"operationId":"onboarding_start_managed_account","summary":"Provision a managed OCS sub-account (step 2, primary path)","description":"Re-links the org to its EXISTING sub-account under Carrier's reseller and switches the org to managed mode, removing any stored BYO token. Idempotent and read-only on OCS: it matches the org id inside an existing `listResellerAccount` account name. OCS exposes no createAccount method (G-05), so when no such account exists — or the master credential is missing — the response is still 200 with `pending: true`, a `pending_reason` of `account_absent` / `account_conflict` / `not_configured` / `ocs_unavailable`, and `managed_path_chosen` recorded so the operator can reach Stripe Connect without a paid plan (CAR-288). Never writes account_mode=managed without a live sub-account id.","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Managed account ready","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"account_mode":{"type":"string","enum":["managed"]},"subaccount_id":{"type":"string"},"demo":{"type":"boolean"},"switched_from_byo":{"type":"boolean"}}}}}}}},"401":{"description":"Unauthorized"},"502":{"description":"Sub-account provisioning failed"}}}},"/v1/onboarding/plan":{"post":{"operationId":"onboarding_save_plan","summary":"Record the starting plan template (step 3)","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["templateId","displayName"],"properties":{"templateId":{"type":"string","maxLength":256},"displayName":{"type":"string","maxLength":128}}}}}},"responses":{"200":{"description":"Saved","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"The `onboarding:<org>` record after the step","additionalProperties":true}}}}}},"400":{"description":"Invalid body"},"401":{"description":"Unauthorized"}}}},"/v1/onboarding/plan/skip":{"post":{"operationId":"onboarding_skip_plan","summary":"Skip the plan step (step 3)","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Skipped","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","description":"The `onboarding:<org>` record after the step","additionalProperties":true}}}}}},"401":{"description":"Unauthorized"}}}},"/v1/onboarding/test-esim":{"post":{"operationId":"onboarding_test_esim","summary":"Preview one eSIM from the connected fleet (step 4)","description":"Nothing is provisioned — this reads back the first subscriber OCS returns. Every failure degrades to a demo ICCID with a `demo_reason`, because a blocked last step is worse than an obviously fake number.","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"An ICCID, real or demo","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"iccid":{"type":"string"},"demo":{"type":"boolean"},"demo_reason":{"type":"string","enum":["no_token","no_subscribers","ocs_error"]}}}}}}}},"401":{"description":"Unauthorized"}}}},"/v1/onboarding/complete":{"post":{"operationId":"onboarding_complete","summary":"Mark onboarding complete (step 5)","tags":["Onboarding"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Completed","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"completed":{"type":"boolean"}}}}}}}},"401":{"description":"Unauthorized"}}}},"/v1/operator-billing/stripe-webhook":{"post":{"operationId":"operator_billing_stripe_webhook","summary":"Stripe Connect lifecycle webhook (no bearer auth — Stripe-Signature header required)","tags":["Webhooks"],"security":[],"parameters":[{"name":"stripe-signature","in":"header","required":false,"schema":{"type":"string"},"description":"Stripe webhook signature (Svix format)"}],"requestBody":{"required":true,"description":"Raw Stripe event payload","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"responses":{"200":{"description":"Event acknowledged","content":{"application/json":{"schema":{"type":"object","properties":{"received":{"type":"boolean"}}}}}},"400":{"description":"Invalid signature or payload"},"503":{"description":"Billing DB not configured"}}}},"/v1/webhooks/bridge4ip":{"post":{"operationId":"receive_bridge4ip_webhook","summary":"Receive Bridge4IP push event (usage, eSIM status, location)","tags":["Webhooks"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"description":"Bridge4IP native payload — one of UsageNotification, EsimStatus, or LocationCallback shapes","content":{"application/json":{"schema":{"type":"object","description":"Bridge4IP event payload","example":{"iccid":"89001012012341234512","imsi":"310150123456789","status":"Enable"}}}}},"responses":{"200":{"description":"Event received and normalized"},"401":{"description":"Invalid webhook bearer token"},"503":{"description":"Webhook not configured"}}}},"/v1/subscribers/{iccid}/phone-number":{"put":{"operationId":"affect_subscriber_phone_number","summary":"Assign a fake or real MSISDN to a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"phoneNumber":"+31612345678","phoneType":"fake"}}}}}}},"/v1/subscribers/{iccid}/mobile-plan":{"put":{"operationId":"modify_subscriber_mobile_plan","summary":"Change the mobile plan assigned to a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"mobilePlanId":42}}}}}}},"/v1/subscribers/{iccid}/voip-plan":{"put":{"operationId":"modify_subscriber_voip_plan","summary":"Change the VoIP plan assigned to a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"voipPlanId":7}}}}}}},"/v1/subscribers/{iccid}/steering-list/push":{"post":{"operationId":"push_steering_to_subscriber","summary":"Push the assigned steering list down to the subscriber's SIM","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers/{iccid}/packages/{packageId}/active-period":{"put":{"operationId":"modify_subscriber_package_active_period","summary":"Change the active period of a prepaid package on a subscriber","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"packageId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"startDate":"2026-09-01","endDate":"2026-09-30"}}}}}}},"/v1/subscribers/{iccid}/cell-location":{"get":{"operationId":"get_subscriber_location_by_cell_id","summary":"Resolve the subscriber's last radio cell tuple to lat/lon via Bridge4IP GeoSense. Returns 404 when that radio has no cell tower tuple.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"},"cell":{"type":"object","description":"Cell tuple taken from the subscriber's last radio and sent to GeoSense","required":["radioType","mcc","mnc","lac"],"properties":{"radioType":{"type":"string","enum":["2G","3G","4G","5G","NB-IoT"]},"mcc":{"type":"integer"},"mnc":{"type":"integer"},"lac":{"type":"integer"},"cellId":{"type":"integer"}}}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/subscribers/{iccid}/gz-counter/reset":{"post":{"operationId":"reset_subscriber_gz_counter","summary":"Reset the Green Zone volume counter for a subscriber (admin only, irreversible)","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/destination-lists":{"get":{"operationId":"list_destination_lists","summary":"List destination lists with full prefix detail","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"resellerId","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["array","object","null"],"description":"OCS listDetailedDestinationList payload, passed through. null when the reseller has no destination lists."}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/voip-tariffs":{"get":{"operationId":"list_subscriber_voip_tariff","summary":"List the VoIP tariff catalog available to a reseller","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"resellerId","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":["array","object","null"],"description":"OCS listSubscriberVoipTariff payload, passed through. null when the reseller has no VoIP tariffs."}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/voip-tariffs/{voipPlanId}/rules":{"get":{"operationId":"list_voip_tariff_rule","summary":"List the rate rules for one VoIP plan","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"voipPlanId","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/location-zones/{locationZoneId}/network-profile":{"put":{"operationId":"change_network_profile_of_location_zone","summary":"Attach or change the network profile on an existing location zone. Admin scope and a confirm token, because this addresses a zone by id and other tenants may route through it.","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"locationZoneId","in":"path","required":true,"schema":{"type":"integer"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Single-use confirm token (120s TTL). Omit to receive a new token; include to execute.","schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"networkProfileId":12}}}}}}},"/v1/network-default":{"get":{"operationId":"get_network_default","summary":"Read the org network default (cheapest_available, all or custom) and what applies today. New assignments only.","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}},"put":{"operationId":"set_network_default","summary":"Set the org network default. Stored only; touches no SIM and writes nothing to OCS. Applies to new assignments.","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"mode":"cheapest_available"}}}}}}},"/v1/network-default/plan":{"post":{"operationId":"plan_network_default","summary":"Plan which networks a SIM gets in given countries: the cheapest available by default, unless the org or this call overrides it. Read only; falls back to all networks with an explicit warning when the tariff is missing.","tags":["Network"],"security":[{"bearerAuth":[]}],"parameters":[],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","additionalProperties":true,"example":{"countries":["CA"],"simOverride":{"mode":"all"}}}}}}}},"/v1/reseller/webhook-config":{"get":{"operationId":"carrier_webhook_config","summary":"Read the Bridge4IP relay flags and notification webhooks for this reseller","tags":["Reseller"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"resellerId","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"202":{"description":"Confirm token required (admin hard-block)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfirmTokenRequired"}}}},"400":{"description":"Bad request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope or tier upgrade required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"Not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Quota exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QuotaExceeded"}}}},"502":{"description":"OCS upstream error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OcsError"}}}}}}},"/v1/ai/chat":{"post":{"operationId":"ai_chat","summary":"Ask the assistant about your fleet. Streams the answer.","description":"Server-Sent Events. `event: quota` carries the allowance after this call, `event: delta` frames carry `{ text }`, and one `event: done` ends the stream. `event: error` means the answer stopped early; the allowance is still spent, because it is reserved before the model runs.","tags":["AI"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["question"],"properties":{"question":{"type":"string","maxLength":2000},"history":{"type":"array","description":"Prior turns. At most the last 10 are used.","items":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant"]},"content":{"type":"string"}}}},"panel":{"type":"string","description":"Narrows the assistant to one console panel's subject."}},"example":{"question":"Which subscribers cost the most this week?"}}}}},"responses":{"200":{"description":"Event stream","content":{"text/event-stream":{"schema":{"type":"string"}}}},"400":{"description":"Missing or oversized question","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"429":{"description":"Included AI questions used up for this period"},"503":{"description":"AI is not enabled or not configured on this deployment"}}}},"/v1/ai/insights":{"post":{"operationId":"ai_insights","summary":"Generated insight cards for the caller's fleet","description":"Always 200. `generated` is `\"ai\"` when a model wrote the cards and `\"measured\"` when it did not — no credentials, allowance spent, or upstream failure — in which case the cards are the measured figures. Clients must show the difference: the two are different claims.","tags":["AI"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Cards, AI-written or measured","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"generated":{"type":"string","enum":["ai","measured"]},"cards":{"type":"array","items":{"type":"object","properties":{"title":{"type":"string"},"body":{"type":"string"},"severity":{"type":"string","enum":["critical","attention","healthy","info"]},"action":{"type":"string"},"metricKey":{"type":"string"}}}}}}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/ai/quota":{"get":{"operationId":"ai_quota","summary":"AI allowance remaining. Reads without consuming.","description":"`available` is whether the deployment can call a model at all; `remaining` is how much of this tier's allowance is left. They are separate because \"AI is off here\" and \"you are out of calls\" are different facts and need different words.","tags":["AI"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Allowance","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer"},"remaining":{"type":"integer"},"window":{"type":"string","enum":["day","month"]},"resetsAt":{"type":"string","format":"date-time"},"tier":{"type":"string","enum":["free","pro","enterprise","superadmin"]},"available":{"type":"boolean"}}}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/invoices/periods":{"get":{"operationId":"list_invoice_periods","summary":"Billing periods for the caller's org, newest first","description":"At most 24 periods. A period is the month an invoice bills for, and its id is what POST /v1/invoices takes as `period_id`.","tags":["Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Periods","content":{"application/json":{"schema":{"type":"object","properties":{"periods":{"type":"array","items":{"$ref":"#/components/schemas/InvoicePeriod"}}}}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/config":{"get":{"operationId":"get_billing_config","summary":"Billing config for the caller's org","description":"Creates the row with defaults on first read, so this never 404s: USD, cycle day 1, zero rates, prefix INV, Stripe not connected.","tags":["Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfig"}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"update_billing_config","summary":"Update billing config. Requires the 'write' scope.","description":"Every field is optional and an omitted field keeps its current value. `billing_cycle_day` and the Stripe fields cannot be set here: the first is fixed, the second belongs to the Connect onboarding routes.","tags":["Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"currency":{"type":"string","enum":["USD","EUR","GBP","CHF"]},"price_per_gb_cents":{"type":"integer","minimum":0},"platform_fee_bps":{"type":"integer","minimum":0,"maximum":10000},"invoice_prefix":{"type":"string","maxLength":10}},"example":{"currency":"EUR","price_per_gb_cents":450,"invoice_prefix":"ACME"}}}}},"responses":{"200":{"description":"Config after the update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BillingConfig"}}}},"400":{"description":"Body was not JSON, or failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope 'write' required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/stripe/connect/begin":{"post":{"operationId":"stripe_connect_begin","summary":"Start Stripe Connect onboarding (free-tier; Clerk auth only).","description":"Returns a Stripe onboarding URL to send the operator to. The Express account is created on the first call and reused after that, so calling this again mints a fresh link for the same account rather than a second account. `account_type` is accepted but Carrier creates an Express account either way. Does not require a paid write scope or an OCS token — this is the stranger 'Start selling now' path (CAR-288). Payouts and invoice writes still require the write scope.","tags":["Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["return_url","refresh_url"],"properties":{"return_url":{"type":"string","format":"uri"},"refresh_url":{"type":"string","format":"uri"},"account_type":{"type":"string","enum":["express","standard"],"default":"express"}},"example":{"return_url":"https://app.carrier.llc/billing/connected","refresh_url":"https://app.carrier.llc/billing/retry"}}}}},"responses":{"200":{"description":"Onboarding link","content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"}}}}}},"400":{"description":"Body was not JSON, or failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"502":{"description":"Stripe refused the account or the account link","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Billing database or Stripe key not configured on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/stripe/connect/status":{"get":{"operationId":"stripe_connect_status","summary":"Stripe Connect account status for the caller's org","description":"Asks Stripe when an account exists and writes the answer back, so this is how a pending account becomes active. With no account, or when the Stripe call fails, it answers from the stored config with every capability flag false. `requirements`, `capabilities` and `payout_schedule` are always null today.","tags":["Billing"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Connect status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/StripeConnectStatus"}}}},"401":{"description":"Unauthorized"},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices":{"get":{"operationId":"list_invoices","summary":"List invoices for the caller's org, newest first","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["draft","sent","paid","void"]}},{"name":"year","in":"query","required":false,"schema":{"type":"integer","minimum":2024,"maximum":2100}},{"name":"month","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":12}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0}}],"responses":{"200":{"description":"Page of invoices. `total` counts the filtered set, not the page.","content":{"application/json":{"schema":{"type":"object","properties":{"invoices":{"type":"array","items":{"$ref":"#/components/schemas/Invoice"}},"total":{"type":"integer"},"offset":{"type":"integer"},"limit":{"type":"integer"}}}}}},"400":{"description":"A query parameter failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_invoice","summary":"Bill a period from its call records. Requires the 'write' scope.","description":"Aggregates the org's CDR events for the period into one line per ICCID, prices each at `price_per_gb_cents` (falling back to the org rate when zero or omitted), adds the configured platform fee, and stores the result as a draft. Nothing is sent to the recipient here. The figures are frozen at creation, so running this again after late CDRs arrive produces a second invoice rather than correcting the first.","tags":["Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["period_id"],"properties":{"period_id":{"type":"string","minLength":1},"currency":{"type":"string","enum":["USD","EUR","GBP","CHF"],"default":"USD"},"recipient_name":{"type":"string","maxLength":200},"recipient_email":{"type":"string","format":"email"},"notes":{"type":"string","maxLength":2000},"price_per_gb_cents":{"type":"integer","minimum":0,"default":0,"description":"Overrides the org rate for this invoice. 0 uses the org rate."}},"example":{"period_id":"per_2026_07","recipient_name":"Acme BV","price_per_gb_cents":450}}}}},"responses":{"201":{"description":"Draft invoice","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Body was not JSON, or failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope 'write' required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"No period with that id belongs to the caller's org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}":{"get":{"operationId":"get_invoice","summary":"One invoice with its line items and period","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"inv_k3m9xq2b7t1w"}],"responses":{"200":{"description":"Invoice, line items and period","content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Invoice"},{"type":"object","properties":{"line_items":{"type":"array","items":{"$ref":"#/components/schemas/InvoiceLineItem"}},"period":{"$ref":"#/components/schemas/InvoicePeriod"}}}]}}}},"401":{"description":"Unauthorized"},"404":{"description":"No invoice with that id belongs to the caller's org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"update_invoice","summary":"Update invoice status or recipient. Requires the 'write' scope.","description":"Omitted fields keep their current value. Moving the status to `sent` stamps `issued_at` once and later updates do not restamp it. `paid` cannot be set here, because payment is recorded from Stripe.","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"inv_k3m9xq2b7t1w"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["draft","sent","void"]},"recipient_name":{"type":"string","maxLength":200},"recipient_email":{"type":"string","format":"email"},"notes":{"type":"string","maxLength":2000}},"example":{"status":"sent","recipient_email":"ap@acme.example"}}}}},"responses":{"200":{"description":"Invoice after the update","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Invoice"}}}},"400":{"description":"Body was not JSON, or failed validation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope 'write' required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"No invoice with that id belongs to the caller's org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The invoice is void and cannot be updated. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"void_invoice","summary":"Void an invoice. Requires the 'write' scope.","description":"A void, not a delete: the row stays and its status becomes `void`, so the numbering and the audit trail survive. A paid invoice cannot be voided.","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"inv_k3m9xq2b7t1w"}],"responses":{"200":{"description":"Voided","content":{"application/json":{"schema":{"type":"object","required":["voided"],"properties":{"voided":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized"},"402":{"description":"Scope 'write' required","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UpgradeRequired"}}}},"404":{"description":"No invoice with that id belongs to the caller's org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The invoice is paid and cannot be voided. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/invoices/{id}/pdf":{"get":{"operationId":"get_invoice_document","summary":"Download the invoice document. Not JSON.","description":"Two content types, both 200, so a client has to read the header rather than assume. A stored PDF is streamed as `application/pdf` with a download disposition. Otherwise the same invoice is rendered as `text/html` for inline display, because Workers cannot run the PDF renderer in V8. Errors are still JSON.","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"example":"inv_k3m9xq2b7t1w"}],"responses":{"200":{"description":"The stored PDF, or an HTML rendering when no PDF exists","content":{"application/pdf":{"schema":{"type":"string","format":"binary"}},"text/html":{"schema":{"type":"string"}}}},"401":{"description":"Unauthorized"},"404":{"description":"No invoice with that id belongs to the caller's org","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectivity/plans":{"get":{"operationId":"list_connectivity_plans","summary":"List test plans and live plans available to this account","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Test plans, then this account's products, then storefront rows this caller may draw. A product price is catalogue data and is not charged here.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityPlanList"}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/products":{"get":{"operationId":"list_connectivity_products","summary":"List connectivity products this account defined","description":"Newest first, up to 100. These are connectivity.plan objects. Defining one does not debit a wallet.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Products on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityPlanList"}}}},"401":{"description":"Unauthorized"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"create_connectivity_product","summary":"Define a connectivity plan for this account","description":"Idempotency-Key is required. The same key and body return the original plan. Countries, allowance, and price are what the operator writes; this call does not look up coverage and does not debit a wallet. package_template_id is the OCS template used later, when an intent is issued from the caller's own account. The write scope is required.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityProductCreate"}}}},"responses":{"200":{"description":"Replay of the same Idempotency-Key and body","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityPlan"}}}},"201":{"description":"The plan this account can now issue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityPlan"}}}},"400":{"description":"Invalid product"},"402":{"description":"Write scope required"},"409":{"description":"Idempotency-Key reused with a different body. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectivity/products/{id}":{"get":{"operationId":"get_connectivity_product","summary":"Retrieve one connectivity product","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"cnp_…"}}],"responses":{"200":{"description":"The plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityPlan"}}}},"404":{"description":"No such plan on this account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectivity/intents":{"get":{"operationId":"list_connectivity_intents","summary":"List connectivity intents for this account","description":"Newest first. The default page is 20. limit is 1–100.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Intents on this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntentList"}}}},"400":{"description":"limit is not an integer from 1 to 100"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}},"post":{"operationId":"create_connectivity_intent","summary":"Issue one eSIM, or leave the intent waiting for a plan","description":"Idempotency-Key is required. The same key and body return the original intent and do not draw a second SIM. Plans prefixed test_ (test_global_1gb, test_eu_1gb) succeed immediately, set livemode false, and never call the network — including on the free tier. A product id (cnp_…) is a plan this account defined. Any other id is a live catalogue slug. Live plans draw one eSIM from the caller's own account. The price on a product is not charged by this call.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,199}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntentCreate"},"example":{"plan":"test_global_1gb","metadata":{"order":"123"}}}}},"responses":{"200":{"description":"Replay of an existing idempotency key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntent"}}}},"201":{"description":"Intent created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntent"}}}},"202":{"description":"Issuance still in progress","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntent"}}}},"400":{"description":"Invalid body, unknown plan, or no account for a live plan"},"402":{"description":"Live plan requested without the write scope"},"409":{"description":"Idempotency key reused with a different body. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}},"503":{"description":"Connectivity storage is not configured"}}}},"/v1/connectivity/intents/{id}":{"get":{"operationId":"get_connectivity_intent","summary":"Retrieve one connectivity intent","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The intent","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntent"}}}},"404":{"description":"No intent with that id on this account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/intents/{id}/confirm":{"post":{"operationId":"confirm_connectivity_intent","summary":"Attach a plan and issue the eSIM","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["plan"],"properties":{"plan":{"type":"string"}}}}}},"responses":{"200":{"description":"Plan applied, or the intent was already terminal","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityIntent"}}}},"202":{"description":"Issuance still in progress"},"400":{"description":"Missing plan, or the plan cannot be drawn"},"404":{"description":"No intent with that id on this account"},"409":{"description":"A different plan is already set. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}}}}},"/v1/connectivity/webhook_endpoints":{"post":{"operationId":"create_connectivity_webhook_endpoint","summary":"Register an HTTPS endpoint. The signing secret is returned once.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityWebhookEndpointCreate"},"example":{"url":"https://example.com/carrier/webhooks"}}}},"responses":{"201":{"description":"Endpoint created. secret is not returned again.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityWebhookEndpointCreated"}}}},"400":{"description":"URL is missing, not https, or contains credentials"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}},"get":{"operationId":"list_connectivity_webhook_endpoints","summary":"List webhook endpoints. Secrets are omitted.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Endpoints for this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityWebhookEndpointList"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/webhook_endpoints/{id}":{"delete":{"operationId":"delete_connectivity_webhook_endpoint","summary":"Remove a webhook endpoint","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityWebhookEndpointDeleted"}}}},"404":{"description":"No endpoint with that id on this account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/events":{"get":{"operationId":"list_connectivity_events","summary":"List recent connectivity events for this account","description":"Newest first, at most 20. Pass intent to keep only events for that connectivity intent.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"intent","in":"query","required":false,"schema":{"type":"string","description":"cni_… Restricts the list to that intent."}}],"responses":{"200":{"description":"Newest first, at most 20","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityEventList"}}}},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/events/{id}":{"get":{"operationId":"get_connectivity_event","summary":"Retrieve one connectivity event","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The event","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityEvent"}}}},"404":{"description":"No event with that id on this account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/usage_records":{"post":{"operationId":"create_connectivity_usage_record","summary":"Record usage on a test intent. Live intents are metered by the network.","description":"Idempotency-Key is required. The same key and quantity return the original record. A live intent returns network_metered and is not stored: the prepaid wallet is already debited by the metering cron, and a second report would charge the same bytes twice.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":255}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityUsageRecordCreate"},"example":{"intent":"cni_0123456789abcdef0123456789abcdef","quantity_mb":12.5}}}},"responses":{"200":{"description":"Replay of an existing idempotency key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityUsageRecord"}}}},"201":{"description":"Usage recorded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityUsageRecord"}}}},"400":{"description":"Invalid quantity, intent not succeeded, or live intent"},"404":{"description":"No intent with that id on this account"},"409":{"description":"Idempotency key reused with a different quantity or intent. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}}}},"get":{"operationId":"list_connectivity_usage_records","summary":"List usage records for one intent","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"intent","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Newest first, at most 20","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityUsageRecordList"}}}},"404":{"description":"No intent with that id on this account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/connectivity/events/{id}/retry":{"post":{"operationId":"retry_connectivity_event","summary":"Re-sign and POST an existing event. Does not create a second event.","tags":["Connectivity"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Redelivered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConnectivityEvent"}}}},"404":{"description":"No event with that id on this account"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}}}}},"/v1/subscribers/issue-from-inventory":{"post":{"operationId":"issue_esim_from_inventory","summary":"Issue a free eSIM from an account's inventory and assign a package","description":"Durable inventory issuance requires BILLING_DB and a stable X-Idempotency-Key (Idempotency-Key is an alias). The atomically claimed key permits at most one provider dispatch, not provider exactly-once delivery. Replays recheck caller/tenant/account authorization and the account/template/window fingerprint. Preserve the key after OUTCOME_UNKNOWN or MANUAL_RECONCILIATION_REQUIRED; never automatically reissue. Managed and scoped BYO callers may select only an authorized positive account.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"X-Idempotency-Key","in":"header","required":true,"schema":{"type":"string","minLength":1,"maxLength":200,"pattern":"^[A-Za-z0-9][A-Za-z0-9_.:-]{0,199}$"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["packageTemplateId"],"properties":{"packageTemplateId":{"type":"integer"},"accountId":{"type":"integer","description":"Required for BYO when the org has no default account."},"startDate":{"type":"string","description":"With endDate, mapped to activePeriod.start (LocalDateTime). OCS has no startDate field. A start without an end is refused. Omit both dates to activate at first use."},"endDate":{"type":"string","description":"With startDate, mapped to activePeriod.end (LocalDateTime). A bare date means 23:59:59."},"validityPeriod":{"type":"integer","minimum":1,"description":"Days from now. Cannot be combined with startDate or endDate."}}}}}},"responses":{"200":{"description":"Replay of an issuance that already succeeded"},"201":{"description":"eSIM issued","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object"}}}}}},"400":{"description":"packageTemplateId or accountId missing"},"402":{"description":"Scope 'write' required"},"404":{"description":"Managed caller named another account, or the replay key belongs to another caller, organization or issuance channel"},"409":{"description":"NO_INVENTORY, ISSUANCE_IN_PROGRESS, locked prior outcome, OUTCOME_UNKNOWN or MANUAL_RECONCILIATION_REQUIRED. Preserve the same key; no automatic reissue.. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}},"502":{"description":"Provider rejected the issuance"},"503":{"description":"LEDGER_REQUIRED: durable storage is unavailable; no mutation is permitted"}}}},"/v1/subscribers/issue-from-inventory/{idempotencyKey}":{"delete":{"operationId":"rollback_esim_issuance","summary":"Roll back one operator issuance by its idempotency key","description":"Releases the package OCS assigned. Current caller/account ownership is rechecked. The conditional rollback_pending claim locks the issuance before the call; only a confirmed provider release records rolled_back. An ambiguous response records rollback_unknown and must not reissue. A row with no subsPackageId cannot be rolled back automatically.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"idempotencyKey","in":"path","required":true,"schema":{"type":"string"}},{"name":"X-Confirm-Token","in":"header","required":false,"description":"Omit to receive a single-use token (120s). Send it back to run the rollback.","schema":{"type":"string"}}],"responses":{"200":{"description":"Provider release confirmed, then ledger marked rolled_back. Body includes rolled_back: true."},"202":{"description":"Confirm token issued. Send it back to run the rollback."},"400":{"description":"Confirm token missing or expired"},"402":{"description":"Scope 'write' required"},"403":{"description":"Confirm token belongs to another session"},"404":{"description":"No operator issuance with that key for this caller"},"409":{"description":"Issuance is not in issued status, or was already rolled back. Or org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"oneOf":[{"$ref":"#/components/schemas/Error"},{"$ref":"#/components/schemas/OrgNotConnected"}]}}}},"422":{"description":"No subsPackageId was recorded, so the package cannot be released automatically"},"502":{"description":"Provider release failed or is ambiguous; rollback_unknown remains locked, not rolled_back"},"503":{"description":"Issuance ledger is not available"}}}},"/v1/subscribers/{iccid}/country-history":{"get":{"operationId":"subscriber_country_history","summary":"Recent country.entered events for one subscriber","description":"Reads the OCS event ring. limit defaults to 20 and must be 1–50.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":50}}],"responses":{"200":{"description":"Newest country events","content":{"application/json":{"schema":{"type":"object","required":["country_events"],"properties":{"country_events":{"type":"array","items":{"type":"object"}}}}}}},"400":{"description":"ICCID is not 19–20 digits, or limit is outside 1–50"},"404":{"description":"Subscriber not found"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Subscriber lookup or the event ring failed"}}}},"/v1/subscribers/{iccid}/notes":{"get":{"operationId":"get_subscriber_notes","summary":"Operator notes for one subscriber","description":"OCS has no notes field. `notes` is the fleet drawer's single blob (empty string when unset). `data` is the support desk's append-only history, newest first, at most 100 entries. Both are scoped to the caller's org.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Blob plus history","content":{"application/json":{"schema":{"type":"object","required":["notes","data"],"properties":{"notes":{"type":"string"},"data":{"type":"array","items":{"type":"object","required":["id","iccid","orgId","authorId","authorName","content","createdAt"],"properties":{"id":{"type":"string"},"iccid":{"type":"string"},"orgId":{"type":"string"},"authorId":{"type":"string"},"authorName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}}},"400":{"description":"ICCID is not 19–20 digits"},"404":{"description":"Managed session does not own this subscriber"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Managed subscriber lookup failed"},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"operationId":"add_subscriber_note","summary":"Append one support note","description":"Body is { note, author? }. note is 1–4000 characters after trim. Writes an entry; it does not change the fleet blob.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["note"],"properties":{"note":{"type":"string","minLength":1,"maxLength":4000},"author":{"type":"string","maxLength":120}}}}}},"responses":{"201":{"description":"Stored entry","content":{"application/json":{"schema":{"type":"object","required":["note"],"properties":{"note":{"type":"object","required":["id","iccid","orgId","authorId","authorName","content","createdAt"],"properties":{"id":{"type":"string"},"iccid":{"type":"string"},"orgId":{"type":"string"},"authorId":{"type":"string"},"authorName":{"type":"string"},"content":{"type":"string"},"createdAt":{"type":"string","format":"date-time"}}}}}}}},"400":{"description":"ICCID, note, or author failed validation"},"402":{"description":"Scope 'write' required"},"404":{"description":"Managed session does not own this subscriber"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Managed subscriber lookup failed"},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"operationId":"put_subscriber_notes","summary":"Replace the fleet note blob","description":"Body is { notes }. notes is a string of at most 4000 characters. Empty string clears the blob. Does not append history.","tags":["Subscribers"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"iccid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["notes"],"properties":{"notes":{"type":"string","maxLength":4000}}}}}},"responses":{"200":{"description":"Blob stored","content":{"application/json":{"schema":{"type":"object","required":["ok","notes"],"properties":{"ok":{"type":"boolean"},"notes":{"type":"string"}}}}}},"400":{"description":"ICCID or notes failed validation"},"402":{"description":"Scope 'write' required"},"404":{"description":"Managed session does not own this subscriber"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"502":{"description":"Managed subscriber lookup failed"},"503":{"description":"Billing database not bound on this deployment","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/v1/connectivity/events/observe":{"post":{"operationId":"observe_connectivity_event","summary":"Record a bridge network event against the intent that owns the ICCID","description":"Called by the ocs-bridge. Authorization is CARRIER_INTERNAL_API_KEY, not a Clerk session. An unknown bridge_type is ignored with 200.","tags":["Connectivity"],"security":[{"internalBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["org_id","iccid","bridge_type"],"properties":{"org_id":{"type":"string"},"iccid":{"type":"string"},"bridge_type":{"type":"string"}}}}}},"responses":{"200":{"description":"Event already recorded, or the bridge type is ignored"},"201":{"description":"Event recorded"},"400":{"description":"org_id, iccid, or bridge_type missing"},"401":{"description":"Internal key missing or wrong"},"404":{"description":"No succeeded intent for that ICCID"},"503":{"description":"Internal ingest or the billing database is not configured"}}}},"/v1/connectivity/usage_records/ingest":{"post":{"operationId":"ingest_connectivity_usage","summary":"Ingest one metered usage line from the bridge","description":"Called by the ocs-bridge. Authorization is CARRIER_INTERNAL_API_KEY, not a Clerk session. ref is the idempotency key.","tags":["Connectivity"],"security":[{"internalBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["org_id","iccid","ref","quantity_mb"],"properties":{"org_id":{"type":"string"},"iccid":{"type":"string"},"ref":{"type":"string"},"quantity_mb":{"type":"number","exclusiveMinimum":0,"maximum":1000000}}}}}},"responses":{"200":{"description":"This ref was already ingested"},"201":{"description":"Usage stored"},"400":{"description":"Body failed validation"},"401":{"description":"Internal key missing or wrong"},"404":{"description":"No succeeded intent for that ICCID"},"503":{"description":"Internal ingest or the billing database is not configured"}}}},"/v1/cdr/ingest":{"post":{"operationId":"ingest_cdr_events","summary":"Store a batch of CDR events for the caller's org","description":"Insert OR IGNORE on event id. A repeated id counts as skipped. At most 1000 events.","tags":["Billing"],"security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["events"],"properties":{"events":{"type":"array","minItems":1,"maxItems":1000,"items":{"type":"object","required":["id","iccid","event_ts"],"properties":{"id":{"type":"string"},"iccid":{"type":"string"},"subscriber_ref":{"type":"string"},"event_ts":{"type":"integer","description":"Unix milliseconds"},"bytes_up":{"type":"integer"},"bytes_down":{"type":"integer"},"network":{"type":"string"},"country":{"type":"string","minLength":2,"maxLength":2},"session_id":{"type":"string"}}}}}}}}},"responses":{"201":{"description":"Batch stored","content":{"application/json":{"schema":{"type":"object","required":["ingested","skipped"],"properties":{"ingested":{"type":"integer"},"skipped":{"type":"integer"}}}}}},"400":{"description":"Body failed validation"},"402":{"description":"Scope 'write' required"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database is not bound"}}}},"/v1/cdr/aggregate":{"get":{"operationId":"aggregate_cdr","summary":"Sum CDR bytes for one month, grouped by ICCID","description":"At most 1000 ICCIDs, largest total first. Pass iccid to read one subscriber.","tags":["Billing"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"year","in":"query","required":true,"schema":{"type":"integer","minimum":2024,"maximum":2100}},{"name":"month","in":"query","required":true,"schema":{"type":"integer","minimum":1,"maximum":12}},{"name":"iccid","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"Monthly rollup","content":{"application/json":{"schema":{"type":"object","required":["org_id","year","month","lines","total_bytes","generated_at"],"properties":{"org_id":{"type":"string"},"year":{"type":"integer"},"month":{"type":"integer"},"lines":{"type":"array","items":{"type":"object"}},"total_bytes":{"type":"integer"},"generated_at":{"type":"string"}}}}}},"400":{"description":"year or month missing or out of range"},"409":{"description":"org_not_connected: the active organization has no Carrier account but the caller belongs to one that does. Switch back to `switch_to`, or connect this organization at `connect_url`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrgNotConnected"}}}},"503":{"description":"Billing database is not bound"}}}},"/api/templates":{"get":{"operationId":"list_storefront_templates","summary":"Sellable storefront plans, as a bare array","description":"Public. An operator with no curated plans gets an empty array. The storefront treats a non-array as an upstream failure.","tags":["Storefront"],"security":[],"responses":{"200":{"description":"Sellable plans","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","required":["id","name","description","dataGb","validityDays","price_cents","currency","regions","features"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"dataGb":{"type":"number"},"validityDays":{"type":"integer"},"price_cents":{"type":"integer"},"currency":{"type":"string"},"regions":{"type":"array","items":{"type":"string"}},"features":{"type":"array","items":{"type":"string"}}}}}}}},"503":{"description":"Billing database is not bound"}}}},"/api/orders":{"get":{"operationId":"list_storefront_buyer_orders","summary":"List eSIMs one buyer paid for on one shop","description":"Requires CARRIER_STOREFRONT_API_KEY as a bearer token. The shop checks Clerk, then calls this with the buyer's email and the published storefront slug. An email alone is not a lookup.","tags":["Storefront"],"security":[{"storefrontBearer":[]}],"parameters":[{"name":"storefront","in":"query","required":true,"schema":{"type":"string"},"description":"Published storefront slug."},{"name":"email","in":"query","required":true,"schema":{"type":"string"},"description":"Buyer email the shop already verified with Clerk."}],"responses":{"200":{"description":"Orders for that buyer on that shop","content":{"application/json":{"schema":{"type":"object","required":["orders"],"properties":{"orders":{"type":"array","items":{"type":"object","required":["orderId","status"],"properties":{"orderId":{"type":"string"},"status":{"type":"string","enum":["pending","provisioning","ready","failed"]},"templateId":{"type":"string"},"planName":{"type":"string"},"iccid":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"qrCode":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"activationCode":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"smdpAddress":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"matchingId":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"createdAt":{"type":"string"},"failureMessage":{"type":"string"},"dataGb":{"type":"number","description":"Data allowance in GB copied from the plan at purchase. A legacy order with no snapshot uses the plan's current row. Omitted when unlimited or unknown."},"unlimited":{"type":"boolean","description":"Present and true only when the purchased plan was explicitly unlimited."},"validityDays":{"type":"integer","description":"Validity in days copied from the plan at purchase. A legacy order with no snapshot uses the plan's current row. Omitted when the plan does not say."}}}}}}}}},"400":{"description":"Email is missing or not an address"},"401":{"description":"Storefront API key is missing or does not match"},"404":{"description":"No published storefront with that slug"},"503":{"description":"Billing database or storefront API key is not configured"}}}},"/api/orders/{orderId}/usage":{"get":{"operationId":"get_storefront_order_usage","summary":"Data used by the order's own eSIM","description":"Reads usage for the ICCID stored on this order, never for an ICCID from the request. usedBytes is the total since the order was created. An OCS failure is 502, never a 200 with usedBytes 0.","tags":["Storefront"],"security":[{},{"storefrontBearer":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"storefront","in":"query","required":false,"schema":{"type":"string"},"description":"Published storefront slug. Required for an order that belongs to a hosted storefront."}],"responses":{"200":{"description":"Usage","content":{"application/json":{"schema":{"type":"object","required":["iccid","usedBytes","measuredAt"],"properties":{"iccid":{"type":"string"},"usedBytes":{"type":"number"},"measuredAt":{"type":"string"}}}}}},"401":{"description":"Storefront API key is set and the bearer does not match"},"404":{"description":"No order with that id on this storefront"},"409":{"description":"The eSIM has not been issued yet"},"502":{"description":"Usage could not be read"},"503":{"description":"Usage is not available"}}}},"/api/orders/{orderId}/top-up-options":{"get":{"operationId":"get_storefront_order_top_up_options","summary":"Plans the buyer can add to this order's eSIM","description":"The shop's own sellable plans. An empty array means nothing can be added, including when the order is cancelled.","tags":["Storefront"],"security":[{},{"storefrontBearer":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"storefront","in":"query","required":false,"schema":{"type":"string"},"description":"Published storefront slug. Required for an order that belongs to a hosted storefront."}],"responses":{"200":{"description":"Plans","content":{"application/json":{"schema":{"type":"array","items":{"type":"object"}}}}},"401":{"description":"Storefront API key is set and the bearer does not match"},"404":{"description":"No order with that id on this storefront"},"503":{"description":"Order fulfilment is not available"}}}},"/api/orders/{orderId}/top-up-checkouts/{sessionId}/cancel":{"post":{"operationId":"cancel_storefront_top_up_checkout","summary":"Cancel an outstanding top-up checkout for this order","description":"Expires one open, unpaid top-up Checkout Session recorded against this order. A session that already reached paid is never expired here and returns 409 so a person reconciles it. Fails closed (502) when the payment state cannot be verified.","tags":["Storefront"],"security":[{},{"storefrontBearer":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"storefront","in":"query","required":false,"schema":{"type":"string"},"description":"Published storefront slug. Required for an order that belongs to a hosted storefront."},{"name":"sessionId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Checkout expired or confirmed unpaid, no charge","content":{"application/json":{"schema":{"type":"object","required":["cancelled"],"properties":{"cancelled":{"type":"boolean"},"paymentState":{"type":"string"}}}}}},"401":{"description":"Storefront API key is set and the bearer does not match"},"404":{"description":"No open top-up checkout with that session id on this order"},"409":{"description":"The checkout was already paid and needs reconciliation"},"502":{"description":"Payment state could not be verified; cancellation was not applied"},"503":{"description":"Checkout cancellation is not available"}}}},"/api/orders/{orderId}/cancel":{"post":{"operationId":"cancel_storefront_order","summary":"Record the buyer's cancel","description":"Records the cancel so the order accepts no further top-up. It refunds nothing and changes nothing at the network. A second call returns the same time. Releasing the eSIM is the separate operator rollback on DELETE /api/orders/{orderId}.","tags":["Storefront"],"security":[{},{"storefrontBearer":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"storefront","in":"query","required":false,"schema":{"type":"string"},"description":"Published storefront slug. Required for an order that belongs to a hosted storefront."}],"responses":{"200":{"description":"Cancelled","content":{"application/json":{"schema":{"type":"object","required":["cancelledAt"],"properties":{"cancelledAt":{"type":"string","nullable":true}}}}}},"401":{"description":"Storefront API key is set and the bearer does not match"},"404":{"description":"No order with that id on this storefront"},"503":{"description":"Order fulfilment is not available"}}}},"/api/orders/{orderId}":{"get":{"operationId":"get_storefront_order","summary":"Read one storefront order","description":"The body is the order object itself. When CARRIER_STOREFRONT_API_KEY is set, the caller must send it as a bearer token. When it is unset, the route is open and the order id is the only secret.","tags":["Storefront"],"security":[{},{"storefrontBearer":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}},{"name":"storefront","in":"query","required":false,"schema":{"type":"string"},"description":"Published storefront slug. Required to read an order that belongs to a hosted storefront."}],"responses":{"200":{"description":"The order","content":{"application/json":{"schema":{"type":"object","required":["orderId","status"],"properties":{"orderId":{"type":"string"},"status":{"type":"string","enum":["pending","provisioning","ready","failed"]},"templateId":{"type":"string"},"planName":{"type":"string"},"iccid":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"qrCode":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"activationCode":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"smdpAddress":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"matchingId":{"type":"string","description":"Present only when the eSIM is ready and has not been cancelled."},"createdAt":{"type":"string"},"expiresAt":{"type":"string"},"failureMessage":{"type":"string"}}}}}},"401":{"description":"Storefront API key is set and the bearer does not match"},"404":{"description":"No order with that id on this storefront"},"503":{"description":"Billing database is not bound"}}},"delete":{"operationId":"rollback_storefront_order","summary":"Cancel one storefront order and release its eSIM (CAR-264 rollback)","description":"Requires CARRIER_STOREFRONT_API_KEY as a bearer token — unlike the read-only lookup on this same path, this is a destructive write. Mirrors DELETE /v1/subscribers/issue-from-inventory/{idempotencyKey} on the operator channel against the same esim_issuances ledger row, keyed by storefrontIdempotencyKey(orderId), so either channel can release an eSIM it issued without a reconciliation job needing to know which one provisioned it. Only orders in status \"ready\" can be rolled back. The order and issuance-ledger transitions use separate conditional claims; they are not an atomic transaction or a provider delivery guarantee. Confirmed release and an unknown provider outcome are distinct. An ambiguous release requires manual reconciliation and must not automatically reissue.","tags":["Storefront"],"security":[{"storefrontBearer":[]}],"parameters":[{"name":"orderId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order rolled back and the eSIM package released in OCS","content":{"application/json":{"schema":{"type":"object","required":["rolled_back","order_id"],"properties":{"data":{"type":"object"},"rolled_back":{"type":"boolean"},"order_id":{"type":"string"}}}}}},"401":{"description":"Storefront API key is missing or does not match"},"404":{"description":"No order with that id"},"409":{"description":"Order is not in status \"ready\" — already rolled back, or not yet issued (code ALREADY_ROLLED_BACK or INVALID_STATE)"},"422":{"description":"Order has no recorded subsPackageId and cannot be rolled back automatically"},"502":{"description":"Order and ledger were marked rolled back, but OCS release failed or is not configured"},"503":{"description":"Billing database is not bound, or CARRIER_STOREFRONT_API_KEY is not configured"}}}},"/api/hosted/{slug}":{"get":{"operationId":"get_hosted_storefront","summary":"Published hosted storefront, including its sellable plans","tags":["Storefront"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The published storefront"},"404":{"description":"Unknown or unpublished slug"}}}},"/api/hosted/{slug}/plans/{planId}/readiness":{"get":{"operationId":"get_hosted_storefront_plan_readiness","summary":"Read-only readiness check using the fulfilment owner's account rules","tags":["Storefront"],"security":[],"parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"}},{"name":"planId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Current readiness; no account or credential is exposed","content":{"application/json":{"schema":{"type":"object","required":["ready"],"additionalProperties":false,"properties":{"ready":{"type":"boolean"},"reason":{"type":"string","description":"Why the plan is not ready, e.g. the credential cannot see the issuing account."},"test_mode":{"type":"boolean","description":"Present and true when the shop is in Stripe test mode: test sales use a mock eSIM, so readiness never blocks on OCS."},"live_ready":{"type":"boolean","nullable":true,"description":"Test mode only: the verdict a live sale would get; null when it could not be determined."},"live_reason":{"type":"string","description":"Test mode only: why a live sale would be refused."},"live_error":{"type":"string","description":"Test mode only: the live check failed or timed out (e.g. account_check_unavailable, timeout)."}}}}}},"404":{"description":"Unknown or unpublished storefront, or inactive/unknown plan"},"503":{"description":"Account ownership cannot currently be confirmed; retry later"}}}},"/v1/storefronts":{"get":{"operationId":"list_storefronts","summary":"List hosted storefronts for the caller's organization","tags":["Storefront"],"security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Storefronts"},"403":{"description":"No organization on the caller"}}},"post":{"operationId":"create_storefront","summary":"Create a hosted storefront","tags":["Storefront"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","description":"Shop address. Acme Mobile is stored as acme-mobile."},"name":{"type":"string"},"status":{"type":"string","enum":["draft","published"]},"theme":{"type":"object"},"copy":{"type":"object"},"order_notify_email":{"type":"string","description":"Operator mail address for per-order notifications. Falls back to the shop's support email. Invalid addresses are ignored."},"order_notify_webhook_url":{"type":"string","description":"Operator webhook URL for per-order notifications (order.ready / order.failed), signed with X-Carrier-Signature. Invalid URLs are ignored."}}}}}},"responses":{"200":{"description":"Replay of the same Idempotency-Key"},"201":{"description":"Created"},"409":{"description":"Slug taken, or the key was reused for a different body"}}}},"/v1/storefronts/orders":{"get":{"operationId":"list_storefront_orders","summary":"List orders across the caller's storefronts, newest first. Metadata only — no ICCID, QR, or activation codes.","tags":["Storefront"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"storefront_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["pending","provisioning","ready","failed"]}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Orders"},"400":{"description":"Invalid status or limit"},"403":{"description":"No organization on the caller"}}}},"/v1/storefronts/{id}":{"get":{"operationId":"get_storefront","summary":"Read one hosted storefront owned by the caller","tags":["Storefront"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The storefront"},"404":{"description":"Not found"}}},"patch":{"operationId":"update_storefront","summary":"Update a hosted storefront. Omitted fields are left as they are.","tags":["Storefront"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"slug":{"type":"string","description":"Shop address. Acme Mobile is stored as acme-mobile."},"name":{"type":"string"},"status":{"type":"string","enum":["draft","published"]},"theme":{"type":"object"},"copy":{"type":"object"},"order_notify_email":{"type":"string","description":"Operator mail address for per-order notifications. Falls back to the shop's support email. Invalid addresses are ignored."},"order_notify_webhook_url":{"type":"string","description":"Operator webhook URL for per-order notifications (order.ready / order.failed), signed with X-Carrier-Signature. Invalid URLs are ignored."}}}}}},"responses":{"200":{"description":"Updated"},"404":{"description":"Not found"}}}},"/v1/storefronts/{id}/plans":{"post":{"operationId":"upsert_storefront_plan","summary":"Create or replace a plan on a hosted storefront. product_id copies a connectivity plan owned by the caller.","tags":["Storefront"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"Send product_id to copy a connectivity plan owned by the caller. Optional price_cents overrides the retail price. Or send slug, name, price_cents, currency, and ocs_package_template_id.","properties":{"product_id":{"type":"string","description":"Connectivity plan id, such as cnp_…"},"slug":{"type":"string"},"name":{"type":"string"},"price_cents":{"type":"integer"},"currency":{"type":"string"},"ocs_package_template_id":{"type":"integer"},"data_gb":{"type":"number","description":"Gigabytes. 0 is refused unless unlimited is true: the only way to sell an unlimited plan."},"unlimited":{"type":"boolean","description":"The only way to sell an unlimited plan. A 0 or missing data_gb without this is refused."},"validity_days":{"type":"integer"},"regions":{"type":"array","items":{"type":"string"},"description":"ISO country codes, such as DE. Omit to leave the saved list unchanged."},"description":{"type":"string","description":"Buyer-facing sentence. Omit to leave the saved text unchanged."},"active":{"type":"boolean"},"stripe_price_id":{"type":"string","nullable":true,"description":"Existing Stripe Price id (price_…, 1-255 characters), stored, not yet charged. Set together with stripe_price_mode. Null clears both. Omit both to leave the stored Price. The later checkout must verify the Price on the connected account. Buyers cannot set this."},"stripe_price_mode":{"type":"string","nullable":true,"enum":["test","live"],"description":"test or live, matching the organization's Stripe mode. Set together with stripe_price_id. Null clears both. Omit both to leave the stored Price."}}}}}},"responses":{"200":{"description":"Plan saved"},"404":{"description":"Storefront not found (not_found), or ocs_account_id is not an OCS account of the caller's organization (account_not_found)"},"503":{"description":"account_check_unavailable: ownership of ocs_account_id could not be verified right now (credential store or OCS unavailable). Nothing was written. Retry later.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["account_check_unavailable","unavailable"]},"message":{"type":"string"}},"required":["error","message"]}}}}}}},"/v1/storefronts/{id}/plans/{slug}":{"patch":{"operationId":"update_storefront_plan","summary":"Change the price, sale state, display order, or stored Stripe Price of an existing plan. The Price id and its mode are set together; null clears both. The Price is stored, not yet charged. Omitted fields stay as stored. A plan on another storefront is not found.","tags":["Storefront"],"security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"slug","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"price_cents":{"type":"integer","minimum":1,"description":"Retail price in minor units. Must be greater than zero."},"active":{"type":"boolean","description":"Whether the plan is for sale."},"sort_order":{"type":"integer","minimum":0},"stripe_price_id":{"type":"string","nullable":true,"description":"Existing Stripe Price id (price_…, 1-255 characters), stored, not yet charged. Set together with stripe_price_mode. Null clears both. Omit both to leave the stored Price. The later checkout must verify the Price on the connected account. Buyers cannot set this."},"stripe_price_mode":{"type":"string","nullable":true,"enum":["test","live"],"description":"test or live, matching the organization's Stripe mode. Set together with stripe_price_id. Null clears both. Omit both to leave the stored Price."}}}}}},"responses":{"200":{"description":"Plan updated"},"400":{"description":"Price is not a positive number of minor units"},"404":{"description":"Storefront or plan not found (not_found), or ocs_account_id is not an OCS account of the caller's organization (account_not_found)"},"503":{"description":"account_check_unavailable: ownership of ocs_account_id could not be verified right now (credential store or OCS unavailable). Nothing was written. Retry later.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","enum":["account_check_unavailable","unavailable"]},"message":{"type":"string"}},"required":["error","message"]}}}}}}},"/health":{"get":{"operationId":"health_check","summary":"Health check — returns build metadata","tags":["System"],"security":[],"responses":{"200":{"description":"Healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}}}}