openapi: 3.0.0 info: version: '2026.06' title: Dyspatch Blocks SMS Drafts API description: '# Introduction The Dyspatch API is based on the REST paradigm, and features resource based URLs with standard HTTP response codes to indicate errors. We use standard HTTP authentication and request verbs, and all responses are JSON formatted. See our [Implementation Guide](https://docs.dyspatch.io/development/implementing_dyspatch/) for more details on how to implement Dyspatch. ## Generating API Clients Dyspatch provides OpenAPI specifications for our API which can be used to generate API clients in various programming languages. We recommend using [OpenAPI Generator](https://github.com/OpenAPITools/openapi-generator). To download the latest OpenAPI specifications, click the Download button at the top of this page. To download a specific version, view the [changelog](https://docs.dyspatch.io/api/changelog.html) and select the desired version. ' contact: name: Dyspatch Support url: https://docs.dyspatch.io email: support@dyspatch.io termsOfService: https://www.dyspatch.io/legal/terms-of-service/ servers: - url: https://api.dyspatch.io tags: - name: SMS Drafts description: 'SMS Drafts represent unpublished versions of templates that are still mutable. There could be many in progress drafts for a template. ' paths: /sms/drafts: get: operationId: getSMSDrafts security: - Bearer: [] summary: List SMS Drafts description: Returns all SMS drafts for your organization. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/cursor' - $ref: '#/components/parameters/status' - $ref: '#/components/parameters/draftTemplateFilter' - $ref: '#/components/parameters/version' responses: '200': description: Drafts headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: application/vnd.dyspatch.2026.06+json: schema: $ref: '#/components/schemas/DraftsRead' '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/publishRequest: post: operationId: submitSMSDraftForApproval security: - Bearer: [] summary: Submit SMS Draft for Approval description: Moves the SMS draft into submitted state. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' responses: '200': description: Successfully submitted '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/publish/approve: post: operationId: approveSMSDraft security: - Bearer: [] summary: Approve SMS Draft description: Approves an SMS draft that is in Design or Publish review. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' requestBody: description: Optional Feedback for the approval content: text/plain: schema: type: string required: false responses: '200': description: Successfully submitted '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/publish/approveAll: post: operationId: approveSMSDraftForAll security: - Bearer: [] summary: Approve SMS Draft For All Reviewers description: Approves an SMS draft that is in Design or Publish review for all reviewers. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' requestBody: description: Optional Feedback for the approval content: text/plain: schema: type: string required: false responses: '200': description: Successfully submitted '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/publish/reject: post: operationId: rejectSMSDraft security: - Bearer: [] summary: Reject SMS Draft description: Rejects an SMS draft that is in Design or Publish review. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' requestBody: description: Optional Feedback for the rejection content: text/plain: schema: type: string required: false responses: '200': description: Successfully submitted '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/duplicate: post: operationId: duplicateSMSDraft security: - Bearer: [] summary: Duplicate SMS Draft description: Creates a copy of an SMS draft with a new name. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' requestBody: description: Name for the new draft content: application/json: schema: type: object required: - name properties: name: type: string description: Name of the new draft required: true responses: '200': description: Successfully duplicated draft content: application/json: schema: type: object properties: id: type: string description: ID of the newly created draft '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/lockForTranslation: put: operationId: lockSMSDraftForTranslation security: - Bearer: [] summary: Lock SMS Draft for Translation description: Locks an SMS draft to prevent edits while translations are being completed. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' responses: '204': description: Successfully locked draft for translation '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' delete: operationId: unlockSMSDraftForTranslation security: - Bearer: [] summary: Unlock SMS Draft for Translation description: Unlocks an SMS draft to allow edits after translations are completed. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' responses: '204': description: Successfully unlocked draft for translation '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}: get: operationId: getSMSDraftById security: - Bearer: [] summary: Get SMS Draft by ID description: Gets an SMS draft object with the matching ID. The "compiled" field will contain the template in the default, unlocalized form. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/smsTargetLanguage' - $ref: '#/components/parameters/version' responses: '200': description: A draft object with the requested ID. headers: X-RateLimit-Remaining: description: The number of requests left for the current time window schema: type: integer content: application/vnd.dyspatch.2026.06+json: schema: $ref: '#/components/schemas/SMSDraftRead' '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' delete: operationId: archiveSMSDraft security: - Bearer: [] summary: Archive SMS Draft description: Archives an SMS draft by marking it as deleted. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' responses: '204': description: Successfully archived draft '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/RateLimited' '500': $ref: '#/components/responses/InternalError' default: $ref: '#/components/responses/InternalError' /sms/drafts/{draftId}/localizations: get: operationId: getSMSLocalizationForDraft security: - Bearer: [] summary: Get Localizations on an SMS Draft description: Returns localization metadata for the SMS draft tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' responses: '200': description: A list of localizations headers: X-RateLimit-Remaining: description: The number of requests left for the current time window schema: type: integer content: application/vnd.dyspatch.2026.06+json: schema: type: array items: $ref: '#/components/schemas/LocalizationMetaRead' '400': $ref: '#/components/responses/InvalidRequest' /sms/drafts/{draftId}/localizations/{languageId}: put: operationId: saveSMSLocalization security: - Bearer: [] summary: Create or Update an SMS Localization description: Inserts a localization or sets the name on an existing localization that already uses the languageId tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/languageId' - $ref: '#/components/parameters/version' requestBody: content: application/json: schema: type: object properties: name: type: string example: English (US) required: true responses: '200': description: Successful upsert '400': $ref: '#/components/responses/InvalidRequest' '403': $ref: '#/components/responses/Forbidden' delete: operationId: deleteSMSLocalization security: - Bearer: [] summary: Remove a Localization from SMS Draft description: Deletes the localization with the given language ID if it exists tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/languageId' - $ref: '#/components/parameters/version' responses: '200': description: Successful delete '400': $ref: '#/components/responses/InvalidRequest' /sms/drafts/{draftId}/localizations/{languageId}/translations: get: operationId: getSMSTranslations security: - Bearer: [] summary: Get SMS Draft Translations for Language description: Returns the translations for the given language in key/value pairs. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/languageId' - $ref: '#/components/parameters/version' responses: '200': description: Successful content: application/json: schema: type: object additionalProperties: type: string example: Hello %(name)s: Bonjour %(name)s Welcome: Bienvenue '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' put: operationId: setSMSTranslation security: - Bearer: [] summary: Set SMS Draft Translations for Language description: Completely replaces any existing translations for the given language with those provided in request body. Variables embedded in keys or values are expected to be in the format `%(my_variable)s` and will automatically convert to the correct Dyspatch format depending on the type of template. Accepts key/value pairs in JSON format or in gettext PO file format. For JSON set `Content-Type` header to `application/json`. For gettext PO format set `Content-Type` header to `text/x-gettext-translation`. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/languageId' - $ref: '#/components/parameters/version' requestBody: content: application/json: schema: type: object additionalProperties: type: string example: Hello %(name)s: Bonjour %(name)s Welcome: Bienvenue required: true responses: '200': description: Successful '400': $ref: '#/components/responses/InvalidRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' /sms/drafts/{draftId}/localizationKeys: get: operationId: getSMSDraftLocalizationKeys security: - Bearer: [] summary: Get SMS Draft Localization Keys description: Returns the list of values that need to be translated for the draft. Set the `Accept` header to `application/vnd.dyspatch.2026.06+json` to get a JSON object, or `text/vnd.dyspatch.2026.06+x-gettext-translation` to get the POT file. tags: - SMS Drafts parameters: - $ref: '#/components/parameters/draftId' - $ref: '#/components/parameters/version' responses: '200': description: Localization keys content: application/vnd.dyspatch.2026.06+json: schema: type: array items: $ref: '#/components/schemas/LocalizationKeyRead' text/vnd.dyspatch.2026.06+x-gettext-translation: schema: type: string format: binary '400': $ref: '#/components/responses/InvalidRequest' components: schemas: LocalizationMetaRead: type: object description: localization metadata properties: id: $ref: '#/components/schemas/localizationId' name: $ref: '#/components/schemas/localizationName' url: $ref: '#/components/schemas/localizationUrl' localeGroup: $ref: '#/components/schemas/localeGroupId' languages: $ref: '#/components/schemas/languages' updatedAt: $ref: '#/components/schemas/updatedAt' tagId: type: string example: /An opaque, unique identifier for a tag description: tag_01gpe172x7p6aa1c9grr48efq8 localizationName: type: string example: English (US) description: The user-specified name of a localization DraftsRead: type: object description: list of draft metadata properties: cursor: $ref: '#/components/schemas/cursor' data: type: array items: $ref: '#/components/schemas/DraftMetaRead' description: A list of draft metadata objects languages: type: array items: type: string example: fr-FR description: 'a list of locale codes that are available in the localization. See [supported languages](https://docs.dyspatch.io/localization/supported_languages/) for an exhaustive list of locale codes. ' localizationUrl: type: string example: /localizations/loc_g3L7Cw6Hp5wUaf395LehwK description: The API url for a specific localization APIError: type: object description: possible errors from the api properties: code: type: string enum: - server_error - invalid_parameter - invalid_body - invalid_request - unauthorized - unauthenticated - not_found - rate_limited - prohibited_action description: "Error code:\n * server_error - Internal server error.\n * invalid_parameter - Validation error, parameter will contain invalid field and message will contain the reason.\n * invalid_body - Body could not be parsed, message will contain the reason.\n * invalid_request - Validation error, the protocol used to make the request was not https.\n * unauthorized - Credentials were found but permissions were not sufficient.\n * unauthenticated - Credentials were not found or were not valid.\n * not_found - The requested resource was not found.\n * rate_limited - The request was refused because a rate limit was exceeded. There is an account wide rate limit of 3600 requests per-minute, although that is subject to change. The current remaining rate limit can be viewed by checking the X-Ratelimit-Remaining header.\n * prohibited_action - The request was refused because an action was not valid for the requested resource. Typically this will happen if you try to make changes to a locked resource.\n" message: type: string description: Human readable error message parameter: type: string description: The invalid parameter, if 'code' is invalid_parameter status: type: string example: LOCKED_FOR_TRANSLATION enum: - IN_PROGRESS - PENDING_APPROVAL - LOCKED_FOR_TRANSLATION - UNKNOWN description: 'The status of the current draft: - `IN_PROGRESS`: Draft is actively being edited - `PENDING_APPROVAL`: Draft is awaiting approval - `LOCKED_FOR_TRANSLATION`: Draft is locked pending translation - `UNKNOWN`: Status cannot be determined at this time ' draftName: type: string description: The name of a draft example: Draft Name SMSContent: type: object description: sms draft content properties: type: type: string example: Text description: What type of content this contains (text or image) value: type: string example: This is some text description: The value of the content tagName: type: string example: My Tag description: The user-specified name of a tag cursor: type: object description: Information about paginated results properties: next: type: string description: A cursor to fetch the next page of results hasMore: type: boolean description: Whether there is a next page of results variables: type: array items: type: string example: myVar description: 'a list of variables used in the template ' draftUrl: type: string example: /drafts/tdft_g3L7Cw6Hp5wUaf395LehwK/dft_g3L7Cw6Hp5wU description: The API url for a specific draft templateName: type: string description: The name of a template example: Template Name AssignedTagsMetaRead: type: object description: assigned tags metadata properties: id: $ref: '#/components/schemas/tagId' name: $ref: '#/components/schemas/tagName' draftId: type: string description: An opaque, unique identifier for a draft example: tdft_g3L7Cw6Hp5wU designApprovedDate: type: string format: date-time description: 'If using the design approval workflow this is the date the template draft design was approved, otherwise it will be empty. ' LocalizationKeyRead: type: object description: localization key properties: key: type: string comment: type: string localizationId: type: string description: An opaque, unique identifier for a localization example: loc_g3L7Cw6Hp5wUaf395LehwK SMSCompiledRead: type: object description: revision data properties: sender: type: string example: John Doe description: Sender name phone: type: string example: 123-456-7890 description: Sender phone number content: type: array items: $ref: '#/components/schemas/SMSContent' variables: $ref: '#/components/schemas/variables' templateId: type: string description: An opaque, unique identifier for a template example: tem_g3L7Cw6Hp5wU path: type: string description: The folder path location for this object example: fdr_01gb8vd6pz/fdr_01gqjmdbq/fdr_01gqjmg1 updatedAt: type: string format: date-time description: The time of last update localeGroupId: description: the locale group this localization belongs to, if this field is empty the localization does not belong to any locale group type: string example: lgr_alka38ajla301 SMSDraftRead: type: object description: template draft metadata included latest draft revision properties: id: $ref: '#/components/schemas/draftId' template: $ref: '#/components/schemas/templateId' name: $ref: '#/components/schemas/draftName' url: $ref: '#/components/schemas/draftUrl' path: $ref: '#/components/schemas/path' workspaceId: $ref: '#/components/schemas/workspaceId' compiled: $ref: '#/components/schemas/SMSCompiledRead' createdAt: $ref: '#/components/schemas/createdAt' updatedAt: $ref: '#/components/schemas/updatedAt' localizations: type: array items: $ref: '#/components/schemas/LocalizationMetaRead' description: A list of the Template's available localizations status: $ref: '#/components/schemas/status' templateName: $ref: '#/components/schemas/templateName' designApprovedDate: $ref: '#/components/schemas/designApprovedDate' tags: type: array items: $ref: '#/components/schemas/AssignedTagsMetaRead' description: A list of Tags assigned to the Draft createdAt: type: string format: date-time description: The time of initial creation workspaceId: type: string description: The workspace this object belongs to example: fdr_01gb8vd6pz DraftMetaRead: type: object description: draft metadata properties: id: $ref: '#/components/schemas/draftId' templateId: $ref: '#/components/schemas/templateId' name: $ref: '#/components/schemas/draftName' url: $ref: '#/components/schemas/draftUrl' path: $ref: '#/components/schemas/path' workspaceId: $ref: '#/components/schemas/workspaceId' createdAt: $ref: '#/components/schemas/createdAt' updatedAt: $ref: '#/components/schemas/updatedAt' status: $ref: '#/components/schemas/status' templateName: $ref: '#/components/schemas/templateName' designApprovedDate: $ref: '#/components/schemas/designApprovedDate' tags: type: array items: $ref: '#/components/schemas/AssignedTagsMetaRead' description: A list of Tags assigned to the Draft responses: NotFound: description: Resource not found headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: '*/*': schema: $ref: '#/components/schemas/APIError' InvalidRequest: description: Invalid request headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: '*/*': schema: $ref: '#/components/schemas/APIError' InternalError: description: Server error headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: '*/*': schema: $ref: '#/components/schemas/APIError' Unauthorized: description: Unauthorized headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: '*/*': schema: $ref: '#/components/schemas/APIError' Forbidden: description: Forbidden headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: '*/*': schema: $ref: '#/components/schemas/APIError' RateLimited: description: Rate limit exceeded headers: X-RateLimit-Remaining: description: The number of requests left for the time window. schema: type: integer content: '*/*': schema: $ref: '#/components/schemas/APIError' parameters: languageId: name: languageId in: path description: 'A language ID (eg: en-US)' required: true schema: type: string status: name: status in: query description: Filter the list of drafts by a particular status required: false schema: type: string enum: - LOCKED_FOR_TRANSLATION version: in: header name: Accept required: true description: A version of the API that should be used for the request. For example, to use version "2026.06", set the value to "application/vnd.dyspatch.2026.06+json" schema: type: string draftId: name: draftId in: path description: A draft ID required: true schema: type: string draftTemplateFilter: name: templateId in: query description: Filter drafts by template ID required: false schema: type: string smsTargetLanguage: name: targetLanguage in: query description: The type of templating language to use when compiling the content. required: false schema: type: string enum: - sms - handlebars - liquid - django - jinja - ampscript - klaviyo - brevo - sendpulse - iterablehandlebars - dotdigitalliquid cursor: name: cursor in: query description: A cursor value used to retrieve a specific page from a paginated result set. required: false schema: type: string securitySchemes: Bearer: type: apiKey name: Authorization in: header description: 'Set Bearer followed by your API key as the Authorization header in your API requests. ```shell Authorization: Bearer EXAMPLEAPIKEYXXXXXXXX12345678 ``` Below is an example curl request with an API key in the Authorization header. ```shell curl --request GET \ --url https://api.dyspatch.io/templates \ --header ''Authorization: Bearer EXAMPLEAPIKEYXXXXXXXX12345678'' \ --header ''Accept: application/vnd.dyspatch.2026.06+json'' ``` ' x-tagGroups: - name: Email tags: - Templates - Drafts - Localizations - name: Platform tags: - Workspaces - Blocks - Tags - Customer Profiles - Themes - name: Other Communication Channels tags: - SMS Templates - SMS Drafts - SMS Localizations - Push Templates - Push Drafts - Push Localizations - Live Activity Templates - Live Activity Drafts - Live Activity Localizations - Voice Templates - Voice Drafts - Voice Localizations