openapi: 3.2.0 info: title: Saperly Messaging API version: 0.1.0 description: 'Operations tagged messaging across 2 of this provider''s published API definitions: api-saperly-com-openapi.json, saperly-openapi.yml. Each path carries the servers of the definition it was published in.' servers: - url: / description: This worker - url: https://api.saperly.com description: Production security: [] tags: - name: Messaging description: Send and list SMS messages on your numbers. Outbound sends are billed per segment and pass through opt-out (STOP) and spend-limit enforcement before reaching the carrier; inbound messages are recorded against the receiving number. paths: /messages: post: tags: - Messaging operationId: messaging.send parameters: [] security: [] responses: '201': description: Success content: application/json: schema: type: object properties: id: type: string numberId: type: string direction: type: string enum: - inbound - outbound to: type: string from: type: string body: type: string segments: type: number status: type: string createdAt: type: string required: - id - numberId - direction - to - from - body - segments - status - createdAt additionalProperties: false '400': description: DestinationNotSupported content: application/json: schema: $ref: '#/components/schemas/DestinationNotSupported' '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Unauthorized' '402': description: InsufficientFunds | SpendLimitExceeded content: application/json: schema: anyOf: - $ref: '#/components/schemas/InsufficientFunds' - $ref: '#/components/schemas/SpendLimitExceeded' '403': description: AuthorizationDenied | RecipientOptedOut content: application/json: schema: anyOf: - $ref: '#/components/schemas/AuthorizationDenied' - $ref: '#/components/schemas/RecipientOptedOut' '404': description: NumberNotFound content: application/json: schema: $ref: '#/components/schemas/NumberNotFound' '409': description: IdempotencyConflict content: application/json: schema: $ref: '#/components/schemas/IdempotencyConflict' '422': description: IdempotencyKeyMismatch content: application/json: schema: $ref: '#/components/schemas/IdempotencyKeyMismatch' '429': description: RateLimited content: application/json: schema: $ref: '#/components/schemas/RateLimited' '500': description: InternalError content: application/json: schema: $ref: '#/components/schemas/InternalError' '502': description: MessageSendFailed content: application/json: schema: $ref: '#/components/schemas/MessageSendFailed' summary: Send an SMS message requestBody: content: application/json: schema: type: object properties: fromNumberId: type: string description: The id of one of your numbers to send the SMS from. Must be a number you own; with a scoped key it must also be within the key's number allow-list. to: type: string description: The recipient phone number in E.164 format (e.g. `+14155550123`). body: type: string allOf: - minLength: 1 - maxLength: 1600 description: The message text (1–1600 characters). Long messages are split into multiple segments automatically and billed per segment. required: - fromNumberId - to - body additionalProperties: false description: Send a single SMS. The message is checked against the recipient's opt-out (STOP) status and the workspace balance before it leaves the network. required: true get: tags: - Messaging operationId: messaging.list parameters: - name: numberId in: query schema: anyOf: - type: string description: Filter to messages sent from or received on this number. Omit to list every message in the workspace. - type: 'null' required: false security: [] responses: '200': description: Success content: application/json: schema: type: array items: type: object properties: id: type: string numberId: type: string direction: type: string enum: - inbound - outbound to: type: string from: type: string body: type: string segments: type: number status: type: string createdAt: type: string required: - id - numberId - direction - to - from - body - segments - status - createdAt additionalProperties: false '401': description: Unauthorized content: application/json: schema: $ref: '#/components/schemas/Unauthorized' '403': description: AuthorizationDenied content: application/json: schema: $ref: '#/components/schemas/AuthorizationDenied' '429': description: RateLimited content: application/json: schema: $ref: '#/components/schemas/RateLimited' '500': description: InternalError content: application/json: schema: $ref: '#/components/schemas/InternalError' summary: List messages (optionally filtered by number) servers: - url: / description: This worker components: schemas: MessageSendFailed: type: object properties: _tag: type: string enum: - MessageSendFailed reason: type: string required: - _tag - reason additionalProperties: false RateLimited: type: object properties: _tag: type: string enum: - RateLimited bucket: type: string description: The rate-limit bucket that was exhausted. required: - _tag - bucket additionalProperties: false RecipientOptedOut: type: object properties: _tag: type: string enum: - RecipientOptedOut to: type: string required: - _tag - to additionalProperties: false Unauthorized: type: object properties: _tag: type: string enum: - Unauthorized message: type: string description: Why the request was rejected (missing, invalid, or insufficient credentials). required: - _tag - message additionalProperties: false IdempotencyConflict: type: object properties: _tag: type: string enum: - IdempotencyConflict message: type: string description: Details of the conflict — a concurrent request is still processing under the same `Idempotency-Key`. required: - _tag - message additionalProperties: false DestinationNotSupported: type: object properties: _tag: type: string enum: - DestinationNotSupported to: type: string required: - _tag - to additionalProperties: false SpendLimitExceeded: type: object properties: _tag: type: string enum: - SpendLimitExceeded limitCents: type: number priorSpendCents: type: number requestedCents: type: number required: - _tag - limitCents - priorSpendCents - requestedCents additionalProperties: false InsufficientFunds: type: object properties: _tag: type: string enum: - InsufficientFunds balanceCents: type: number requestedCents: type: number required: - _tag - balanceCents - requestedCents additionalProperties: false InternalError: type: object properties: _tag: type: string enum: - InternalError traceId: type: string description: A correlation id for this failure — quote it when reporting the problem so the request can be traced. required: - _tag - traceId additionalProperties: false AuthorizationDenied: type: object properties: _tag: type: string enum: - AuthorizationDenied reason: type: string required: - _tag - reason additionalProperties: false NumberNotFound: type: object properties: _tag: type: string enum: - NumberNotFound numberId: type: string required: - _tag - numberId additionalProperties: false IdempotencyKeyMismatch: type: object properties: _tag: type: string enum: - IdempotencyKeyMismatch message: type: string description: Why the `Idempotency-Key` is unprocessable — either malformed (e.g. over the length cap) or reused for a request with a different payload. required: - _tag - message additionalProperties: false x-refined-from: - api-saperly-com-openapi.json - saperly-openapi.yml