{"endpoints":[{"method":"post","path":"/v1/messages","group":"Messages","scope":"messages:send","summary":"Send a message","description":"Accepts 04…, +61…, 61… or the same with spaces and brackets. A bare number with no country code and no leading zero is refused rather than guessed. Send an `Idempotency-Key` header and a retry after a timeout can never double-send.","body":{"to":"Destination number (required)","body":"The message. Either this or templateId.","templateId":"A saved template to render instead of `body`.","variables":"Values for the template placeholders.","from":"A registered sender ID. Defaults to the workspace default.","class":"`transactional` (default) or `marketing`. Marketing must carry an unsubscribe URL.","trackLinks":"Rewrite URLs to tracked short links so clicks are recorded and a `link.clicked` event fires. Off by default.","sendAt":"ISO 8601. Hold the message until then, up to a year ahead.","metadata":"Anything you want echoed back on the message and its events."},"example":{"request":{"to":"0412345678","body":"Your order is ready."},"response":{"id":"…","status":"queued","to":"+61412345678","from":"SMS365","segments":1,"encoding":"GSM-7","costCents":10}}},{"method":"post","path":"/v1/messages/bulk","group":"Messages","scope":"messages:send","summary":"Send to many numbers, or to a contact list","description":"Give `to` (up to 1000 numbers) or `groupId`. A group becomes a campaign: expanded as far as the request can manage quickly and finished by a worker, so a large list is not a large HTTP request. Template values come from each contact.","body":{"to":"Up to 1000 numbers. Either this or listId.","groupId":"A saved group of contacts. Personalises from each contact.","body":"The message, or use templateId.","strict":"Refuse the whole request if any number cannot be read.","trackLinks":"Rewrite URLs to tracked short links for every recipient, so click-through is measured per campaign.","sendAt":"ISO 8601, as for a single send."}},{"method":"post","path":"/v1/messages/preview","group":"Messages","scope":"messages:read","summary":"Price a message without sending it","description":"Creates nothing and charges nothing. Returns the encoding, segment count, estimated cost, which numbers are unreadable, and — when a pasted curly quote has forced the message into UCS-2 — a suggested plain-text replacement."},{"method":"post","path":"/v1/ai/draft","group":"Messages","scope":"messages:send","summary":"Draft or improve a message with AI","description":"Generate an SMS from a short brief, or improve an existing one. Needs the platform AI provider to be configured by an admin. Returns the suggested text and the model used.","body":{"prompt":"What the message should say or achieve (required).","tone":"Optional tone, e.g. \"friendly\", \"formal\".","marketing":"If true, the draft ends with an opt-out.","current":"An existing message to improve, instead of writing from scratch."}},{"method":"post","path":"/v1/ai/variations","group":"Messages","scope":"messages:send","summary":"Generate several message options with AI","description":"Returns a few distinct variants to choose from — useful for A/B testing. Needs the platform AI provider configured.","body":{"prompt":"What the message should say or achieve (required).","current":"An existing message to rephrase.","marketing":"If true, each variant ends with an opt-out.","count":"How many variants, 2–5. Default 3."}},{"method":"get","path":"/v1/messages","group":"Messages","scope":"messages:read","summary":"List messages","query":[{"name":"limit","type":"integer","description":"1–200, default 50."},{"name":"status","description":"queued, sending, sent, failed, rejected, cancelled."},{"name":"to","description":"A destination number in any format; it is normalised for you."},{"name":"scheduled","type":"boolean","description":"Only messages held for a future time."},{"name":"batchId","description":"Only messages from one campaign."},{"name":"scope","description":"`family` includes sub-accounts. Owners and admins only."},{"name":"before","description":"ISO 8601, for paging."}]},{"method":"get","path":"/v1/messages/:id","group":"Messages","scope":"messages:read","summary":"Read one message, its full history, and its tracked-link clicks"},{"method":"post","path":"/v1/verify/start","group":"Verify","scope":"verify:write","summary":"Send a one-time code","description":"Generates a numeric code, sends it as a transactional SMS through the same pipeline as any other message, and returns a verification id. The code is never returned or stored — only a keyed hash is kept. Supersedes any code still pending for the same number.","body":{"to":"Destination number (required)","brand":"Shown in the default message: \"Your <brand> code is …\".","template":"A full message with a {code} placeholder, instead of the default wording.","codeLength":"Digits in the code, 4–10. Default 6.","ttlSeconds":"How long the code is valid, 60–3600. Default 600.","maxAttempts":"Wrong tries before the code is spent, 1–10. Default 5.","from":"A registered sender ID. Defaults to the workspace default."},"example":{"request":{"to":"0412345678","brand":"Acme"},"response":{"id":"…","to":"+61412345678","status":"pending","channel":"sms","expiresAt":"…","attemptsRemaining":5}}},{"method":"post","path":"/v1/verify/check","group":"Verify","scope":"verify:write","summary":"Check a code","description":"Give the verification `id` (or the `to` number) and the `code` the user entered. Attempts are capped and the code expires; a settled verification reports its outcome without spending an attempt.","body":{"id":"The verification id from start. Either this or `to`.","to":"The number the code was sent to. Either this or `id`.","code":"What the user typed."},"example":{"request":{"id":"…","code":"123456"},"response":{"id":"…","status":"approved","approved":true,"attemptsRemaining":0}}},{"method":"get","path":"/v1/verify/:id","group":"Verify","scope":"verify:read","summary":"Read a verification’s status"},{"method":"post","path":"/v1/appointments","group":"Appointments","scope":"messages:send","summary":"Schedule reminders for a visit","description":"Give a visit date and the offsets to remind at; SMS365 schedules one message per offset, counting down to the date. Each is a normal scheduled send — charged when scheduled, refunded if the visit is cancelled. Offsets in the past are skipped. Send a `reference` (your booking id) and a repeat call is a no-op instead of a second set of texts.","body":{"to":"The visitor’s number (required).","appointmentAt":"ISO 8601 date-time of the visit (required).","template":"The reminder wording. Use {{when}}, {{date}}, {{time}} and {{name}}.","contactName":"Fills {{name}}. Optional.","reminders":"Offsets, e.g. [\"7d\",\"3d\",\"morning\"]. Default is those three. Units w/d/h/m, or \"morning\".","morningHour":"Hour a \"morning\" reminder goes out, in the visit’s timezone. Default 8.","timezone":"IANA timezone for \"morning\" and formatting. Default Australia/Sydney.","reference":"Your booking id — makes a repeat create idempotent."},"example":{"request":{"to":"0412345678","appointmentAt":"2026-09-20T02:30:00Z","contactName":"Sam","template":"Hi {{name}}, reminder of your visit {{when}}.","reminders":["7d","3d","morning"]},"response":{"id":"…","to":"+61412345678","status":"scheduled","reminders":[{"spec":"7d","sendAt":"…","messageId":"…","status":"scheduled"}]}}},{"method":"get","path":"/v1/appointments","group":"Appointments","scope":"messages:read","summary":"List visits in a date range","query":[{"name":"from","description":"ISO 8601. Start of the window (default ~a month back)."},{"name":"to","description":"ISO 8601. End of the window."}]},{"method":"get","path":"/v1/appointments/defaults","group":"Appointments","scope":"messages:read","summary":"The default reminder offsets and morning hour"},{"method":"get","path":"/v1/appointments/:id","group":"Appointments","scope":"messages:read","summary":"Read a visit and its reminders"},{"method":"post","path":"/v1/appointments/:id/cancel","group":"Appointments","scope":"messages:send","summary":"Cancel a visit and every reminder still to go","description":"Cancels each reminder that has not yet sent and refunds it in full."},{"method":"post","path":"/v1/messages/:id/cancel","group":"Messages","scope":"messages:send","summary":"Cancel a message that has not gone yet","description":"Refunds it in full. A message a worker has already picked up returns 409 rather than a cancellation that did not happen."},{"method":"get","path":"/v1/batches","group":"Campaigns","scope":"campaigns:read","summary":"List campaigns and their progress"},{"method":"get","path":"/v1/batches/:id","group":"Campaigns","scope":"campaigns:read","summary":"Read one campaign","description":"A campaign that meets the daily spend cap pauses rather than fails; it resumes at local midnight from the contact it stopped at."},{"method":"post","path":"/v1/batches/:id/cancel","group":"Campaigns","scope":"campaigns:write","summary":"Stop a campaign","description":"Cancels every message from it that has not gone out, each with its own refund."},{"method":"get","path":"/v1/contacts","group":"Audience","scope":"contacts:read","summary":"List contacts","query":[{"name":"search","description":"Matches name, number or email."},{"name":"groupId","description":"Only contacts in one group."},{"name":"limit","type":"integer","description":"1–500, default 100."},{"name":"offset","type":"integer","description":"For paging."}]},{"method":"post","path":"/v1/contacts","group":"Audience","scope":"contacts:write","summary":"Create or update a contact","description":"Keyed on the normalised number, so sending the same contact twice updates it.","body":{"to":"Number (required)","firstName":"","lastName":"","email":"","attributes":"Any extra values, usable in templates."}},{"method":"delete","path":"/v1/contacts/:id","group":"Audience","scope":"contacts:write","summary":"Delete a contact"},{"method":"post","path":"/v1/contacts/import","group":"Audience","scope":"contacts:write","summary":"Import a spreadsheet","description":"Post CSV as `text/csv`, or JSON as an array of rows. Headers may be called whatever your system calls them — Mobile, Phone Number, MSISDN all resolve. Unrecognised columns become template values. Every unreadable row is returned with its line number and the reason.","query":[{"name":"groupId","description":"Add the imported contacts to this group."}]},{"method":"get","path":"/v1/groups","group":"Audience","scope":"contacts:read","summary":"List groups"},{"method":"post","path":"/v1/groups","group":"Audience","scope":"contacts:write","summary":"Create a group"},{"method":"delete","path":"/v1/groups/:id","group":"Audience","scope":"contacts:write","summary":"Delete a group"},{"method":"post","path":"/v1/groups/:id/members","group":"Audience","scope":"contacts:write","summary":"Add contacts to a group"},{"method":"delete","path":"/v1/groups/:id/members/:contactId","group":"Audience","scope":"contacts:write","summary":"Remove a contact from a group"},{"method":"get","path":"/v1/suppressions","group":"Audience","scope":"suppressions:read","summary":"List blocked numbers"},{"method":"post","path":"/v1/suppressions","group":"Audience","scope":"suppressions:write","summary":"Block a number","description":"Checked before every send from every door, and it cannot be overridden by any caller, permission or flag. Feed your own opt-outs in here."},{"method":"delete","path":"/v1/suppressions/:e164","group":"Audience","scope":"suppressions:write","role":"admin","summary":"Unblock a number"},{"method":"get","path":"/v1/senders","group":"Configuration","scope":"senders:read","summary":"List sender IDs"},{"method":"post","path":"/v1/senders","group":"Configuration","scope":"senders:write","role":"admin","summary":"Register a sender ID","description":"A message can only be sent from a registered ID. Alphanumeric IDs are capped at 11 characters."},{"method":"delete","path":"/v1/senders/:id","group":"Configuration","scope":"senders:write","role":"admin","summary":"Remove a sender ID"},{"method":"get","path":"/v1/templates","group":"Configuration","scope":"templates:read","summary":"List templates"},{"method":"post","path":"/v1/templates","group":"Configuration","scope":"templates:write","summary":"Create or update a template"},{"method":"delete","path":"/v1/templates/:id","group":"Configuration","scope":"templates:write","summary":"Delete a template"},{"method":"patch","path":"/v1/tenant","group":"Configuration","scope":"settings:write","role":"owner","summary":"Change the workspace limits","body":{"dailySpendCapCents":"","rateLimitPerMinute":"","allowedCountryCodes":"e.g. [\"61\"]"}},{"method":"get","path":"/v1/providers","group":"Configuration","scope":"settings:read","summary":"What the carrier can do, and whether sending is available","description":"Read this rather than assuming. MondoTalk reports `deliveryReceipts: false` and `alphanumericSender: false`, which is why no part of this platform claims a message was delivered or that your sender ID reached the handset.\n\nCarrier credentials are the platform operator's and are configured once in the admin console. There is no endpoint to read or change them, and a database constraint makes a workspace-owned carrier account impossible."},{"method":"get","path":"/v1/webhooks","group":"Integrations","scope":"ingress:read","summary":"List inbound webhook endpoints"},{"method":"post","path":"/v1/webhooks","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Create an inbound webhook endpoint","description":"Gives you a URL and a signing secret. Post JSON to it and a template turns it into a text. The secret is returned once."},{"method":"delete","path":"/v1/webhooks/:id","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Delete a webhook endpoint"},{"method":"get","path":"/v1/links","group":"Integrations","scope":"ingress:read","summary":"List trigger URLs"},{"method":"post","path":"/v1/links","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Create a trigger URL","description":"Opening the link shows a confirmation page and sends nothing; `?now=1` skips it. Requests advertising themselves as prefetches are answered and ignored."},{"method":"delete","path":"/v1/links/:id","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Delete a trigger URL"},{"method":"get","path":"/v1/email-ingress","group":"Integrations","scope":"ingress:read","summary":"List email-to-SMS addresses"},{"method":"post","path":"/v1/email-ingress","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Create an email-to-SMS address","description":"Only active members of the workspace can send through it, checked as each message arrives."},{"method":"patch","path":"/v1/email-ingress/:id","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Change an email-to-SMS address"},{"method":"delete","path":"/v1/email-ingress/:id","group":"Integrations","scope":"ingress:write","role":"admin","summary":"Delete an email-to-SMS address"},{"method":"get","path":"/v1/event-types","group":"Integrations","scope":"events:read","summary":"The events SMS365 can send you"},{"method":"get","path":"/v1/events","group":"Integrations","scope":"events:read","summary":"List event subscriptions"},{"method":"post","path":"/v1/events","group":"Integrations","scope":"events:write","role":"admin","summary":"Receive delivery events","description":"Signed the same way SMS365 verifies your inbound webhooks. Non-2xx is retried six times over about eight hours; redirects are not followed."},{"method":"post","path":"/v1/events/:id/enable","group":"Integrations","scope":"events:write","role":"admin","summary":"Re-enable a subscription disabled after repeated failures"},{"method":"post","path":"/v1/events/:id/test","group":"Integrations","scope":"events:write","role":"admin","summary":"Send yourself a test event"},{"method":"get","path":"/v1/events/:id/deliveries","group":"Integrations","scope":"events:read","summary":"Recent delivery attempts for a subscription"},{"method":"delete","path":"/v1/events/:id","group":"Integrations","scope":"events:write","role":"admin","summary":"Delete a subscription"},{"method":"get","path":"/v1/usage","group":"Account","scope":"usage:read","summary":"Balance, spend today and the recent ledger"},{"method":"get","path":"/v1/sub-accounts","group":"Account","scope":"subaccounts:read","summary":"List sub-accounts with what each has sent and spent"},{"method":"post","path":"/v1/sub-accounts","group":"Account","scope":"subaccounts:write","role":"admin","summary":"Create a sub-account","description":"A sub-account has its own messages, contacts, keys and bill, and sends through this workspace's carrier. This workspace's daily cap bounds all of them together."},{"method":"patch","path":"/v1/sub-accounts/:id","group":"Account","scope":"subaccounts:write","role":"admin","summary":"Set a sub-account’s sell rate","description":"Set what you bill this sub-account per segment (in cents). The usage report then shows its revenue and your margin over the platform cost. Send null to bill it at cost.","body":{"sellRateCents":"Cents per segment, or null to clear."}},{"method":"get","path":"/v1/sub-accounts/usage","group":"Account","scope":"usage:read","summary":"Usage per account over a period","description":"Spend is net of refunds and the billable unit is the segment, not the message — so this reconciles against an invoice.","query":[{"name":"period","description":"today, week, month, last_month, fy, all. Default month."},{"name":"from","description":"ISO 8601, for a custom window."},{"name":"to","description":"ISO 8601."}]},{"method":"get","path":"/v1/sub-accounts/usage.csv","group":"Account","scope":"usage:read","summary":"The same report as a spreadsheet"},{"method":"get","path":"/v1/workflows","group":"Configuration","scope":"settings:read","summary":"List packaged workflows and which are enabled"},{"method":"get","path":"/v1/connections","group":"Integrations","scope":"settings:read","summary":"List connected external systems (e.g. Xero)"},{"method":"post","path":"/v1/connections/:provider/sync","group":"Integrations","scope":"settings:write","role":"admin","summary":"Sync a connection now (send reminders for new overdue invoices)"},{"method":"delete","path":"/v1/connections/:provider","group":"Integrations","scope":"settings:write","role":"admin","summary":"Disconnect an external system"},{"method":"post","path":"/v1/workflows/:key","group":"Configuration","scope":"settings:write","role":"admin","summary":"Turn a workflow on or off","body":{"enabled":"true to enable, false to disable."}},{"method":"get","path":"/v1/insights","group":"Account","scope":"usage:read","summary":"Engagement and deliverability: click-through and failure reasons","description":"The complement to the usage report. Returns the send rate (of what reached the carrier), daily volume, the top failure and rejection reasons, and link click-through from tracked links — the one engagement signal available without a carrier delivery receipt.","query":[{"name":"period","description":"today, week, month, last_month, fy, all. Default month."},{"name":"from","description":"ISO 8601, for a custom window."},{"name":"to","description":"ISO 8601."}]},{"method":"get","path":"/v1/audit","group":"Account","scope":"settings:read","role":"admin","summary":"What has been done in this workspace"},{"method":"get","path":"/v1/team","group":"Account","scope":"team:read","summary":"List the people here"},{"method":"post","path":"/v1/team/invites","group":"Account","scope":"team:write","role":"admin","summary":"Invite someone","description":"Returns a link, once. SMS365 sends text messages, not email, so you pass it on yourself."},{"method":"delete","path":"/v1/team/invites/:id","group":"Account","scope":"team:write","role":"admin","summary":"Revoke an invitation"},{"method":"patch","path":"/v1/team/:userId","group":"Account","scope":"team:write","role":"owner","summary":"Change someone’s role"},{"method":"delete","path":"/v1/team/:userId","group":"Account","scope":"team:write","role":"admin","summary":"Remove someone"},{"method":"get","path":"/v1/api-keys","group":"Security","scope":"keys:read","summary":"List API keys","description":"Secrets are never returned; only a prefix that identifies each key."},{"method":"post","path":"/v1/api-keys","group":"Security","scope":"keys:write","role":"admin","summary":"Issue an API key","description":"The full key is returned exactly once. A key issuing another can never grant a permission it does not hold itself.","body":{"name":"Required","description":"What it is for","scopes":"Array of permissions"}},{"method":"delete","path":"/v1/api-keys/:id","group":"Security","scope":"keys:write","role":"admin","summary":"Revoke a key"},{"method":"get","path":"/v1/scopes","group":"Security","summary":"The permission catalogue","description":"Every permission a key can hold, grouped."},{"method":"get","path":"/v1/openapi.json","group":"Security","public":true,"summary":"This API, as OpenAPI 3.1","description":"Unauthenticated, because documentation you need a key to read is not documentation."},{"method":"get","path":"/v1/reference","group":"Security","public":true,"summary":"The same description in a form the console renders"}],"groups":["Messages","Verify","Appointments","Campaigns","Audience","Configuration","Integrations","Account","Security"],"permissions":[{"scope":"messages:send","group":"Messages","label":"Send messages","description":"Send a text, singly or in bulk, and cancel one that has not gone yet."},{"scope":"messages:read","group":"Messages","label":"Read messages","description":"List and inspect messages, including their delivery history."},{"scope":"campaigns:read","group":"Messages","label":"Read campaigns","description":"Follow the progress of a bulk send to a contact list."},{"scope":"campaigns:write","group":"Messages","label":"Manage campaigns","description":"Stop a campaign and cancel everything from it that has not gone out."},{"scope":"verify:write","group":"Messages","label":"Send verification codes","description":"Start a one-time-code verification and check the code a user enters."},{"scope":"verify:read","group":"Messages","label":"Read verifications","description":"Look up the status of a verification."},{"scope":"contacts:read","group":"Audience","label":"Read contacts","description":"List contacts and the groups they belong to."},{"scope":"contacts:write","group":"Audience","label":"Manage contacts","description":"Create, import and delete contacts and groups."},{"scope":"suppressions:read","group":"Audience","label":"Read the suppression list","description":"See which numbers are blocked from receiving anything."},{"scope":"suppressions:write","group":"Audience","label":"Manage the suppression list","description":"Add or remove a number. Use this to feed opt-outs in from your own system."},{"scope":"senders:read","group":"Configuration","label":"Read sender IDs","description":"See the sender IDs registered for this workspace."},{"scope":"senders:write","group":"Configuration","label":"Manage sender IDs","description":"Register or remove a sender ID."},{"scope":"templates:read","group":"Configuration","label":"Read templates","description":"List saved message templates."},{"scope":"templates:write","group":"Configuration","label":"Manage templates","description":"Create and delete message templates."},{"scope":"settings:read","group":"Configuration","label":"Read workspace settings","description":"See the spend cap, rate limit and permitted countries."},{"scope":"settings:write","group":"Configuration","label":"Change workspace settings","description":"Alter the spend cap, rate limit and permitted countries.","dangerous":true},{"scope":"ingress:read","group":"Integrations","label":"Read inbound endpoints","description":"List webhook endpoints, trigger URLs and email-to-SMS addresses."},{"scope":"ingress:write","group":"Integrations","label":"Manage inbound endpoints","description":"Create and delete webhook endpoints, trigger URLs and email addresses."},{"scope":"events:read","group":"Integrations","label":"Read event subscriptions","description":"List where SMS365 sends delivery events, and their recent attempts."},{"scope":"events:write","group":"Integrations","label":"Manage event subscriptions","description":"Add or remove endpoints that receive delivery events."},{"scope":"usage:read","group":"Account","label":"Read usage and spend","description":"Per-account message counts, segments and spend over any period."},{"scope":"subaccounts:read","group":"Account","label":"Read sub-accounts","description":"List sub-accounts and what each has sent and spent."},{"scope":"subaccounts:write","group":"Account","label":"Create sub-accounts","description":"Create a sub-account so its costs are tracked separately."},{"scope":"team:read","group":"Account","label":"Read the team","description":"List the people in this workspace and their roles."},{"scope":"team:write","group":"Account","label":"Manage the team","description":"Invite people, change roles and remove members.","dangerous":true},{"scope":"keys:read","group":"Security","label":"Read API keys","description":"List this workspace's API keys. Secrets are never returned."},{"scope":"keys:write","group":"Security","label":"Create and revoke API keys","description":"Issue new keys and revoke existing ones. A key can never grant a permission it does not itself hold, so this cannot be used to climb.","dangerous":true}],"permissionGroups":[{"group":"Messages","scopes":[{"scope":"messages:send","group":"Messages","label":"Send messages","description":"Send a text, singly or in bulk, and cancel one that has not gone yet."},{"scope":"messages:read","group":"Messages","label":"Read messages","description":"List and inspect messages, including their delivery history."},{"scope":"campaigns:read","group":"Messages","label":"Read campaigns","description":"Follow the progress of a bulk send to a contact list."},{"scope":"campaigns:write","group":"Messages","label":"Manage campaigns","description":"Stop a campaign and cancel everything from it that has not gone out."},{"scope":"verify:write","group":"Messages","label":"Send verification codes","description":"Start a one-time-code verification and check the code a user enters."},{"scope":"verify:read","group":"Messages","label":"Read verifications","description":"Look up the status of a verification."}]},{"group":"Audience","scopes":[{"scope":"contacts:read","group":"Audience","label":"Read contacts","description":"List contacts and the groups they belong to."},{"scope":"contacts:write","group":"Audience","label":"Manage contacts","description":"Create, import and delete contacts and groups."},{"scope":"suppressions:read","group":"Audience","label":"Read the suppression list","description":"See which numbers are blocked from receiving anything."},{"scope":"suppressions:write","group":"Audience","label":"Manage the suppression list","description":"Add or remove a number. Use this to feed opt-outs in from your own system."}]},{"group":"Configuration","scopes":[{"scope":"senders:read","group":"Configuration","label":"Read sender IDs","description":"See the sender IDs registered for this workspace."},{"scope":"senders:write","group":"Configuration","label":"Manage sender IDs","description":"Register or remove a sender ID."},{"scope":"templates:read","group":"Configuration","label":"Read templates","description":"List saved message templates."},{"scope":"templates:write","group":"Configuration","label":"Manage templates","description":"Create and delete message templates."},{"scope":"settings:read","group":"Configuration","label":"Read workspace settings","description":"See the spend cap, rate limit and permitted countries."},{"scope":"settings:write","group":"Configuration","label":"Change workspace settings","description":"Alter the spend cap, rate limit and permitted countries.","dangerous":true}]},{"group":"Integrations","scopes":[{"scope":"ingress:read","group":"Integrations","label":"Read inbound endpoints","description":"List webhook endpoints, trigger URLs and email-to-SMS addresses."},{"scope":"ingress:write","group":"Integrations","label":"Manage inbound endpoints","description":"Create and delete webhook endpoints, trigger URLs and email addresses."},{"scope":"events:read","group":"Integrations","label":"Read event subscriptions","description":"List where SMS365 sends delivery events, and their recent attempts."},{"scope":"events:write","group":"Integrations","label":"Manage event subscriptions","description":"Add or remove endpoints that receive delivery events."}]},{"group":"Account","scopes":[{"scope":"usage:read","group":"Account","label":"Read usage and spend","description":"Per-account message counts, segments and spend over any period."},{"scope":"subaccounts:read","group":"Account","label":"Read sub-accounts","description":"List sub-accounts and what each has sent and spent."},{"scope":"subaccounts:write","group":"Account","label":"Create sub-accounts","description":"Create a sub-account so its costs are tracked separately."},{"scope":"team:read","group":"Account","label":"Read the team","description":"List the people in this workspace and their roles."},{"scope":"team:write","group":"Account","label":"Manage the team","description":"Invite people, change roles and remove members.","dangerous":true}]},{"group":"Security","scopes":[{"scope":"keys:read","group":"Security","label":"Read API keys","description":"List this workspace's API keys. Secrets are never returned."},{"scope":"keys:write","group":"Security","label":"Create and revoke API keys","description":"Issue new keys and revoke existing ones. A key can never grant a permission it does not itself hold, so this cannot be used to climb.","dangerous":true}]}]}