{"components":{"schemas":{"Batch":{"properties":{"accepted":{"type":"integer"},"client_ref":{"nullable":true,"type":"string"},"cost_uusd":{"type":"integer"},"created":{"format":"date-time","type":"string"},"id":{"type":"string"},"mode":{"enum":["live","sandbox"],"type":"string"},"rejected":{"type":"integer"},"requested":{"type":"integer"},"segments":{"type":"integer"}},"required":["id","requested","accepted","rejected","cost_uusd","mode"],"type":"object"},"Error":{"description":"Every failure on this API has exactly these three fields.","properties":{"docs_url":{"description":"Deep link to this code on /docs/errors.","type":"string"},"error":{"description":"Stable machine-readable code. Branch on this.","enum":["insufficient_credit","internal_error","invalid_number","ip_not_allowed","key_expired","key_invalid","key_revoked","message_too_long","method_not_allowed","not_cancellable","not_found","priority_not_allowed","rate_limited","scheduling_not_allowed","scope_denied","sender_blocked","sender_invalid","sender_not_allowed","sender_not_approved","tenant_suspended","too_many_recipients","unauthorized","unicode_not_allowed","unroutable_number","validation_failed"],"type":"string"},"message":{"description":"Written for a developer reading a log.","type":"string"}},"required":["error","message","docs_url"],"type":"object"},"Message":{"properties":{"batch_id":{"nullable":true,"type":"string"},"body":{"type":"string"},"can_cancel":{"type":"boolean"},"carrier":{"enum":["btl","tashicell",null],"nullable":true,"type":"string"},"carrier_name":{"nullable":true,"type":"string"},"client_ref":{"nullable":true,"type":"string"},"created":{"format":"date-time","type":"string"},"delivered_at":{"format":"date-time","nullable":true,"type":"string"},"encoding":{"enum":["gsm7","ucs2"],"type":"string"},"error":{"description":"An error code when the message failed.","nullable":true,"type":"string"},"error_detail":{"nullable":true,"type":"string"},"hold_until":{"format":"date-time","nullable":true,"type":"string"},"id":{"type":"string"},"mode":{"enum":["live","sandbox"],"type":"string"},"price_uusd":{"description":"Micro-USD. 1000000 = $1.","type":"integer"},"priority":{"type":"boolean"},"scheduled_at":{"format":"date-time","nullable":true,"type":"string"},"segments":{"type":"integer"},"sender":{"nullable":true,"type":"string"},"status":{"description":"`charging` exists internally and is never returned.","enum":["queued","sending","submitted","delivered","failed","expired","cancelled","rejected"],"type":"string"},"submitted_at":{"format":"date-time","nullable":true,"type":"string"},"to":{"description":"E.164, as stored.","example":"97517123456","type":"string"},"undo_seconds_remaining":{"type":"integer"},"updated":{"format":"date-time","type":"string"}},"required":["id","to","body","encoding","segments","price_uusd","status","mode","created"],"type":"object"},"Receipt":{"properties":{"error_code":{"nullable":true,"type":"string"},"received_at":{"format":"date-time","type":"string"},"status":{"type":"string"}},"type":"object"}},"securitySchemes":{"apiKeyHeader":{"description":"Accepted identically to the bearer form, for clients that find it easier.","in":"header","name":"X-Api-Key","type":"apiKey"},"bearerAuth":{"description":"`Authorization: Bearer bsk_live_…`. Scopes are carried by the key, not requested per call.","scheme":"bearer","type":"http"}}},"info":{"contact":{"name":"Bhutan SMSC","url":"http://sms.wons.bt/docs"},"description":"Prepaid SMS for Bhutan. Money is integer micro-USD throughout — 1000000 to the dollar — because a float cannot hold a per-segment rate without eventually being a cent out.\n\nSandbox is a property of the KEY, not the request: a `bsk_test_` key simulates everything and charges nothing, and there is no request flag that can be forgotten and accidentally bill you.\n\nThis document is generated from the same tables the routes are built from, so it cannot describe an endpoint this build does not serve.","summary":"One REST endpoint for B-Mobile and TashiCell.","title":"Bhutan SMSC API","version":"1.0.0"},"openapi":"3.0.3","paths":{"/api/quote":{"post":{"description":"The only write-shaped endpoint that needs no key. It exists so a pricing page can be honest before anybody signs up, and it quotes at the entry rate. Once you hold a key, use `POST /api/v1/validate` instead — it quotes at YOUR rate and reports per-recipient outcomes.","operationId":"quote","requestBody":{"content":{"application/json":{"example":{"body":"Your code is 481920","to":"17123456"},"schema":{"properties":{"body":{"description":"The message text. Empty is allowed and quotes zero.","type":"string"},"to":{"description":"Optional recipient. Adds carrier routing to the answer.","type":"string"}},"type":"object"}}},"required":false},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"carrier":{"nullable":true,"properties":{"code":{"type":"string"},"e164":{"type":"string"},"name":{"type":"string"}},"type":"object"},"carrier_error":{"nullable":true,"type":"string"},"characters":{"type":"integer"},"cost_display":{"type":"string"},"cost_uusd":{"type":"integer"},"encoding":{"enum":["gsm7","ucs2"],"type":"string"},"per_segment":{"type":"integer"},"rate_display":{"type":"string"},"rate_uusd":{"type":"integer"},"remaining":{"type":"integer"},"segments":{"type":"integer"},"unicode":{"type":"boolean"}},"type":"object"}}},"description":"OK"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"}},"security":[],"summary":"Price a message with no account at all.","tags":["Status"]}},"/api/v1/balance":{"get":{"description":"Needs the `balance` scope — a `read` key is refused here, so a reporting script can be given message access without being told what you spend.","operationId":"balance","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"balance_display":{"type":"string"},"balance_uusd":{"type":"integer"},"low_balance":{"type":"boolean"},"messages_remaining":{"nullable":true,"type":"integer"},"month_to_date":{"properties":{"from":{"type":"string"},"segments":{"type":"integer"},"spent_display":{"type":"string"},"spent_uusd":{"type":"integer"}},"type":"object"},"plan":{"nullable":true,"properties":{"key":{"type":"string"},"name":{"type":"string"},"retired":{"type":"boolean"}},"type":"object"},"rate_display":{"type":"string"},"rate_uusd_per_segment":{"type":"integer"},"unlimited":{"type":"boolean"}},"type":"object"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"Credit, and what it actually buys.","tags":["Account"]}},"/api/v1/batches/{id}":{"delete":{"description":"Partial success is a 200, not an error: `cancelled` and `already_sent` tell you exactly how much you caught. `complete` is true only when nothing had left already.","operationId":"undo","parameters":[{"description":"The batch id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"already_sent":{"type":"integer"},"batch":{"$ref":"#/components/schemas/Batch"},"cancelled":{"type":"integer"},"complete":{"type":"boolean"},"refunded_uusd":{"type":"integer"}},"type":"object"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not_found"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"Withdraw a whole send.","tags":["Reading"]},"get":{"description":"","operationId":"batch","parameters":[{"description":"The batch id, from a send response.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"batch":{"$ref":"#/components/schemas/Batch"},"messages_url":{"type":"string"},"status_counts":{"additionalProperties":{"type":"integer"},"description":"A status with no messages is ABSENT, not zero.","type":"object"}},"type":"object"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not_found"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"One send, and how its messages are doing.","tags":["Reading"]}},"/api/v1/health":{"get":{"description":"Accepting and delivering are two different facts. `accepting` says a send would be taken and billed; `carrier_delivery` says a gateway exists to hand it to. A build with no gateway configured reports `accepting: true` and `carrier_delivery: false`, and adds a `note` saying so — nothing is lost and nothing needs resending.","operationId":"health","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"accepting":{"type":"boolean"},"api":{"type":"string"},"carrier_delivery":{"type":"boolean"},"gateways":{"items":{"properties":{"name":{"type":"string"},"queued":{"type":"integer"}},"type":"object"},"type":"array"},"note":{"description":"Present only when carrier_delivery is false.","type":"string"},"status":{"type":"string"},"time":{"format":"date-time","type":"string"}},"type":"object"}}},"description":"OK"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"}},"security":[],"summary":"Is the gateway accepting, and is anything being delivered?","tags":["Status"]}},"/api/v1/messages":{"get":{"description":"Filters combine with AND. `charging` rows are never listed — they are the inert moment between insert and payment, not messages you sent.","operationId":"list","parameters":[{"description":"Exact match on one status.","in":"query","name":"status","required":false,"schema":{"type":"string"}},{"description":"Everything accepted in one send.","in":"query","name":"batch","required":false,"schema":{"type":"string"}},{"description":"Recipient, in any format — it is normalised the same way sending is.","in":"query","name":"to","required":false,"schema":{"type":"string"}},{"description":"Your own reference, exact match.","in":"query","name":"client_ref","required":false,"schema":{"type":"string"}},{"description":"ISO-8601 lower bound on `created`, inclusive.","in":"query","name":"since","required":false,"schema":{"type":"string"}},{"description":"ISO-8601 upper bound on `created`, inclusive.","in":"query","name":"until","required":false,"schema":{"type":"string"}},{"description":"1-based. Default: 1.","in":"query","name":"page","required":false,"schema":{"type":"integer"}},{"description":"Clamped to 200. Default: 50.","in":"query","name":"per_page","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"items":{"items":{"$ref":"#/components/schemas/Message"},"type":"array"},"page":{"type":"integer"},"per_page":{"type":"integer"},"total":{"type":"integer"},"total_pages":{"type":"integer"}},"type":"object"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"List your messages, newest first.","tags":["Reading"]},"post":{"description":"Returns **202 Accepted**, not 200 — the message is billed and queued, which is not the same as delivered. Recipients are accepted or rejected individually and you are charged only for the accepted ones.","operationId":"send","parameters":[{"description":"Retry safely. A repeat returns the original batch with `replayed: true` instead of sending again. Scoped to your account.","in":"header","name":"Idempotency-Key","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"example":{"body":"Your code is 481920","to":"17123456"},"schema":{"properties":{"body":{"description":"The text. Never truncated — too long is refused.","type":"string"},"callback_url":{"description":"Per-message receipt callback. See Webhooks for what does and does not fire today.","type":"string"},"client_ref":{"description":"Your own reference, returned on every read. Truncated at 120 characters.","type":"string"},"hold_seconds":{"description":"Your undo window, 0–300. 0 sends immediately.","type":"integer"},"idempotency_key":{"description":"Same as the header. The header wins if both are sent.","type":"string"},"priority":{"description":"Overtake ordinary traffic, at the priority rate.","type":"boolean"},"scheduled_at":{"description":"ISO-8601. Held until due.","type":"string"},"sender":{"description":"An approved sender ID on your account. Omit for the platform default.","type":"string"},"to":{"description":"One value, or an array of them.","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]}},"required":["to","body"],"type":"object"}}},"required":true},"responses":{"202":{"content":{"application/json":{"schema":{"properties":{"accepted":{"type":"integer"},"batch":{"$ref":"#/components/schemas/Batch"},"cost_uusd":{"type":"integer"},"encoding":{"nullable":true,"type":"string"},"hold_seconds":{"description":"Absent on a replayed response.","type":"integer"},"hold_until":{"format":"date-time","nullable":true,"type":"string"},"priority":{"type":"boolean"},"rejected":{"type":"integer"},"replayed":{"description":"True when an Idempotency-Key matched. The results shape differs — see description.","type":"boolean"},"results":{"items":{"properties":{"accepted":{"type":"boolean"},"carrier":{"description":"Fresh accepts only.","type":"string"},"error":{"description":"Fresh rejects only.","type":"string"},"id":{"description":"Replays only.","type":"string"},"message":{"description":"Fresh rejects only.","type":"string"},"segments":{"type":"integer"},"status":{"description":"Replays only.","type":"string"},"to":{"type":"string"}},"required":["to","accepted"],"type":"object"},"type":"array"},"segments":{"nullable":true,"type":"integer"},"sender":{"nullable":true,"type":"string"},"undo_url":{"nullable":true,"type":"string"}},"type":"object"}}},"description":"Accepted and billed. Not delivered — those are different facts."},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"invalid_number, message_too_long, scheduling_not_allowed, too_many_recipients, unicode_not_allowed, unroutable_number, validation_failed"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"402":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"insufficient_credit"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, priority_not_allowed, scope_denied, sender_not_allowed, sender_not_approved, tenant_suspended"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"Send to one recipient or many.","tags":["Sending"]}},"/api/v1/messages/{id}":{"delete":{"description":"Refunds what the message cost. Anything past `queued` returns `not_cancellable` rather than pretending — once a carrier has it, neither we nor SMPP can take it back.","operationId":"cancel","parameters":[{"description":"The message id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"message":{"$ref":"#/components/schemas/Message"},"refunded_uusd":{"type":"integer"}},"type":"object"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not_found"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"409":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not_cancellable"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"Withdraw one message inside its undo window.","tags":["Reading"]},"get":{"description":"Another account's message reads as `not_found`, never as forbidden — a 403 would confirm the id exists.","operationId":"get","parameters":[{"description":"The message id.","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Message"},{"properties":{"receipts":{"items":{"$ref":"#/components/schemas/Receipt"},"type":"array"}},"type":"object"}]}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"not_found"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"One message, with its carrier receipts.","tags":["Reading"]}},"/api/v1/pricing":{"get":{"description":"The authoritative source for `max_tps` — read it here rather than hard-coding a number, because an account can be granted a ceiling above its plan and because there are no rate-limit response headers to discover it from.","operationId":"pricing","responses":{"200":{"content":{"application/json":{"schema":{"properties":{"currency":{"type":"string"},"micro_usd_per_usd":{"example":1000000,"type":"integer"},"plans":{"items":{"properties":{"features":{"properties":{"custom_sender_id":{"type":"boolean"},"delivery_receipts":{"type":"boolean"},"priority_routing":{"type":"boolean"},"priority_send":{"type":"boolean"},"scheduling":{"type":"boolean"},"unicode":{"type":"boolean"},"webhooks":{"type":"boolean"}},"type":"object"},"highlights":{"items":{"type":"string"},"type":"array"},"key":{"type":"string"},"max_recipients_per_request":{"type":"integer"},"max_segments_per_message":{"type":"integer"},"max_tps":{"type":"integer"},"name":{"type":"string"},"price_display":{"type":"string"},"price_uusd_per_segment":{"type":"integer"},"priority_price_display":{"nullable":true,"type":"string"},"priority_uusd_per_segment":{"type":"integer"},"retention_days":{"type":"integer"},"tagline":{"nullable":true,"type":"string"}},"type":"object"},"type":"array"},"unit":{"type":"string"},"unit_note":{"type":"string"}},"type":"object"}}},"description":"OK"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"}},"security":[],"summary":"The live price list and every plan's limits.","tags":["Status"]}},"/api/v1/usage":{"get":{"description":"Days with no traffic are ABSENT from `days`, not present as zero. A day that was not measured and a day with no messages are different facts and this API keeps them apart — plot the gaps as gaps.","operationId":"usage","parameters":[{"description":"YYYY-MM-DD, inclusive. Default: 29 days ago.","in":"query","name":"from","required":false,"schema":{"type":"string"}},{"description":"YYYY-MM-DD, inclusive. Default: today.","in":"query","name":"until","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"days":{"description":"Ascending. A day with no traffic is ABSENT, not zero.","items":{"properties":{"accepted":{"type":"integer"},"by_carrier":{"additionalProperties":{"properties":{"accepted":{"type":"integer"},"delivered":{"type":"integer"},"segments":{"type":"integer"}},"type":"object"},"type":"object"},"cost_uusd":{"type":"integer"},"day":{"type":"string"},"delivered":{"type":"integer"},"expired":{"type":"integer"},"failed":{"type":"integer"},"refunded_uusd":{"type":"integer"},"segments":{"type":"integer"},"submitted":{"type":"integer"}},"type":"object"},"type":"array"},"from":{"type":"string"},"note":{"type":"string"},"totals":{"properties":{"accepted":{"type":"integer"},"cost_display":{"type":"string"},"cost_uusd":{"type":"integer"},"delivered":{"type":"integer"},"expired":{"type":"integer"},"failed":{"type":"integer"},"refunded_uusd":{"type":"integer"},"segments":{"type":"integer"},"submitted":{"type":"integer"}},"type":"object"},"until":{"type":"string"}},"type":"object"}}},"description":"OK"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, tenant_suspended"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"A daily series of what you sent and spent.","tags":["Account"]}},"/api/v1/validate":{"post":{"description":"Free, creates no message, and charges nothing. It runs the same segmenting and routing code the accept path bills with, so its answer is the answer — not an estimate. A bad recipient comes back as `valid: false` inside a 200, not as an HTTP error, because one bad number in fifty is not a failed request.","operationId":"validate","requestBody":{"content":{"application/json":{"example":{"body":"Your code is 481920","to":"17123456"},"schema":{"properties":{"body":{"description":"The message text. Empty quotes zero segments.","type":"string"},"priority":{"description":"Quote at the priority rate instead of the standard one.","type":"boolean"},"sender":{"description":"Check a specific sender ID. Omit for the one your account sends under by default.","type":"string"},"to":{"description":"One value, or an array of them.","oneOf":[{"type":"string"},{"items":{"type":"string"},"type":"array"}]}},"required":["to"],"type":"object"}}},"required":true},"responses":{"200":{"content":{"application/json":{"schema":{"properties":{"message":{"properties":{"characters":{"type":"integer"},"characters_per_segment":{"type":"integer"},"encoding":{"enum":["gsm7","ucs2"],"type":"string"},"exceeds_plan_limit":{"type":"boolean"},"needs_unicode":{"type":"boolean"},"plan_max_segments":{"nullable":true,"type":"integer"},"remaining_in_last_segment":{"type":"integer"},"segments":{"type":"integer"},"unicode_allowed":{"type":"boolean"}},"type":"object"},"priority":{"type":"boolean"},"priority_allowed":{"type":"boolean"},"priority_rate_uusd_per_segment":{"type":"integer"},"rate_display":{"type":"string"},"rate_uusd_per_segment":{"type":"integer"},"recipients":{"description":"Valid recipients only.","type":"integer"},"results":{"description":"One per input, in order. Valid and invalid entries have different shapes.","items":{"properties":{"carrier":{"type":"string"},"carrier_name":{"type":"string"},"cost_display":{"type":"string"},"cost_uusd":{"type":"integer"},"error":{"description":"Only on invalid entries.","type":"string"},"message":{"description":"Only on invalid entries.","type":"string"},"national":{"type":"string"},"to":{"type":"string"},"valid":{"type":"boolean"}},"required":["to","valid"],"type":"object"},"type":"array"},"standard_rate_uusd_per_segment":{"type":"integer"},"total_cost_display":{"type":"string"},"total_cost_uusd":{"type":"integer"}},"type":"object"}}},"description":"OK"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"validation_failed"},"401":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"key_expired, key_invalid, key_revoked, unauthorized"},"403":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"ip_not_allowed, scope_denied, sender_not_allowed, sender_not_approved, tenant_suspended"},"405":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"method_not_allowed"},"429":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"rate_limited"},"500":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"internal_error"}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"summary":"Price and check recipients without creating anything.","tags":["Sending"]}}},"servers":[{"description":"This deployment.","url":"http://sms.wons.bt"}],"tags":[{"name":"Status"},{"name":"Sending"},{"name":"Reading"},{"name":"Account"}]}
