openapi: 3.1.0
info:
title: Postscript Partner API
description: The Postscript Partner API (v2) lets partners and Shopify shops manage SMS subscribers, send custom events
into Flows, send transactional and conversational messages, read opt-in keywords, configure webhook subscriptions, and
run TCPA compliance operations (unsubscribe, redact). Harvested verbatim from the per-operation OpenAPI definitions published
on https://developers.postscript.io/reference.
version: '2.0'
contact:
name: Postscript Developer Support
email: developersupport@postscript.io
url: https://developers.postscript.io
termsOfService: https://postscript.io/api-terms-of-service
servers:
- url: https://api.postscript.io
security:
- sec0: []
tags:
- name: Subscribers
description: Read and update SMS subscribers for a shop.
- name: Events
description: Send custom events for use in Postscript Flows and triggers.
- name: Keywords
description: Read the opt-in keywords configured for a shop.
- name: Messages
description: Send messages and read message requests and sent messages.
- name: Webhooks
description: Create, read, update and delete webhook subscriptions; fetch the signing token, sample payloads and test deliveries.
- name: Compliance
description: TCPA compliance operations — unsubscribe and redact a subscriber.
- name: Identity
description: Verify the identity and scope of the calling API token.
paths:
/api/v2/events:
post:
summary: Create Custom Event
description: Send a Custom Event to use in Flows
operationId: create-custom-event
parameters:
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used *only* by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
required:
- type
properties:
type:
type: string
description: 'The type of event that you are creating. This is the name of the event that will show in the
Postscript application. **Note:** when creating this event, we will *automatically* prefix your partner/shop
name in front of the event. For example, if sending an event called "OrderPlaced", we''ll show it in our
UI as "[Your Partner/Shop Name] - OrderPlaced" to distinguish it from others of a similar name. We accept
the follow characters in the value field: lowercase letters (a-z), uppercase letters (A-Z), digits (0-9),
and underscores (_).'
subscriber_id:
type: string
description: The ID of the subscriber that you are creating the event for.
phone:
type: string
description: The phone number of the subscriber that you are creating the event for. E.164 format is recommended,
but other formats will be accepted.
email:
type: string
description: The email of the subscriber that you are creating the event for.
occurred_at:
type: string
description: 'When the event occurred. This parameter is optional but allows you to set the exact time that
the event occurred on your system. If it is not sent to us, we will just use the current time when we
receive it. The following UTC time format is supported: %Y-%m-%d %H:%M:%S.%f'
format: date
properties:
type: object
description: These are the properties of the event. These properties will be exposed in the Postscript platform
for things like filtering and merge tags to merchants.
properties:
key:
type: string
description: Properties can be key:value pairs. We will attempt to choose the appropriate data type
for the value depending on what you send us. We currently accept strings, booleans, integers, floats,
and datetime strings.
default: value
external_id:
type: string
description: The unique id of the event on your system. This is an optional field. If a value is not provided,
we will create a default id ourselves based on time of event received.
responses:
'202':
description: '202'
content:
application/json:
examples:
Result:
value: "{\n\t\"event_ids\": [\"1234-abcd-5678\"]\n}"
schema:
type: object
properties:
event_ids:
type: array
items:
type: string
example: 1234-abcd-5678
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Events
/api/v2/message_requests:
post:
summary: Send Message
description: Send a message to a subscriber.
operationId: create-message
parameters:
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used *only* by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
required:
- body
properties:
subscriber_id:
type: string
description: The ID of the subscriber to send the message to. Either `subscriber_id` or `phone` is **required**.
phone:
type: string
description: The phone number of the subscriber to send the message to. The subscriber must exist. Either
`phone` or `subscriber_id` is **required**. The phone number of the subscriber you want to send the message
to.
country:
type: string
description: ISO Alpha-2 country code, used to parse `phone` more accurately.
default: US
body:
type: string
description: The message body that you want to send to the subscriber.
category:
type: string
description: The category of message you are sending.
default: promotional
enum:
- promotional
- transactional
- conversational
scheduled_at:
type: string
description: 'ISO 8601 datetime to schedule delivery in the future. Default: `null` (deliver ASAP)'
format: date-time
media_url:
type: string
description: The URL of the media to send with the message. The media can be of type `gif`, `png`, and `jpeg`
and will be formatted correctly on the recipient's device. The media size limit is 1MB for supported file
types (JPEG, PNG, GIF) and 500KB for other types of accepted media. Please note that if you include a
media url with your message, then it gets sent as an MMS message, which has different costs and character
limits than SMS messages.
examples:
Request Example:
value:
phone: '15555555555'
body: Hello, world
category: promotional
media_url: https://example.com/great_pic.png
responses:
'202':
description: '202'
content:
application/json:
examples:
Result:
value: "{\n \"body\": \"string\",\n \"category\": \"promotional\",\n \"created_at\": \"2019-08-24T14:15:22Z\"\
,\n \"id\": \"string\",\n \"phone\": \"string\",\n \"scheduled_at\": \"2019-08-24T14:15:22Z\",\n \"\
sent_message\": {\n \"body\": \"string\",\n \"created_at\": \"2019-08-24T14:15:22Z\",\n \"credits_used\"\
: 0,\n \"id\": \"string\",\n \"media_url\": \"string\",\n \"phone\": \"string\",\n \"shop_id\"\
: \"string\",\n \"subscriber_id\": \"string\"\n },\n \"status\": \"processing\",\n \"status_code\"\
: 0,\n \"subscriber_id\": \"string\",\n \"updated_at\": \"2019-08-24T14:15:22Z\"\n}"
schema:
type: object
properties:
body:
type: string
example: string
category:
type: string
example: promotional
created_at:
type: string
example: '2019-08-24T14:15:22Z'
id:
type: string
example: string
phone:
type: string
example: string
scheduled_at:
type: string
example: '2019-08-24T14:15:22Z'
sent_message:
type: object
properties:
body:
type: string
example: string
created_at:
type: string
example: '2019-08-24T14:15:22Z'
credits_used:
type: integer
example: 0
default: 0
id:
type: string
example: string
media_url:
type: string
example: string
phone:
type: string
example: string
shop_id:
type: string
example: string
subscriber_id:
type: string
example: string
status:
type: string
example: processing
status_code:
type: integer
example: 0
default: 0
subscriber_id:
type: string
example: string
updated_at:
type: string
example: '2019-08-24T14:15:22Z'
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Messages
/api/v2/webhooks:
post:
summary: Create Webhook Subscription
description: ''
operationId: create-webhook-subscription
parameters:
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used only by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
required:
- callback_url
- event
properties:
callback_url:
type: string
description: Destination URL for webhook deliveries (HTTPS only).
event:
type: string
description: Webhook subscription event type.
default: shop.test
enum:
- shop.test
- shop.incoming_message
- shop.subscriber.opt_in
- shop.subscriber.opt_out
- shop.shop.email_collected
headers:
type: object
description: Custom key:value pairs to be sent as headers in every callback.
properties: {}
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"callback_url\": \"http://example.com\",\n \"created_at\": \"2019-08-24T14:15:22Z\",\n \"\
event\": \"shop.test\",\n \"headers\": {},\n \"id\": \"a47606a1-5b39-4a81-9480-c2cb738ff675\",\n \"\
updated_at\": \"2019-08-24T14:15:22Z\",\n}"
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Webhooks
get:
summary: List Webhook Subscriptions
description: ''
operationId: list-webhook-subscriptions
parameters:
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used only by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"webhook_subscriptions\": [\n {\n \"callback_url\": \"http://example.com\",\n \
\ \"created_at\": \"2019-08-24T14:15:22Z\",\n \"event\": \"shop.test\",\n \"headers\": {},\n\
\ \"id\": \"a47606a1-5b39-4a81-9480-c2cb738ff675\",\n \"updated_at\": \"2019-08-24T14:15:22Z\"\
,\n }\n ]\n}"
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Webhooks
/api/v2/webhooks/{id}:
delete:
summary: Delete Webhook Subscription
description: ''
operationId: delete-webhook-subscription
parameters:
- name: id
in: path
description: The ID of the webhook subscription to delete.
schema:
type: string
required: true
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used only by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Webhooks
get:
summary: Get Webhook Subscription
description: ''
operationId: get-webhook-subscription
parameters:
- name: id
in: path
description: ID of the webhook subscription to fetch.
schema:
type: string
required: true
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used only by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"callback_url\": \"http://example.com\",\n \"created_at\": \"2019-08-24T14:15:22Z\",\n \"\
event\": \"shop.test\",\n \"headers\": {},\n \"id\": \"a47606a1-5b39-4a81-9480-c2cb738ff675\",\n \"\
updated_at\": \"2019-08-24T14:15:22Z\",\n}"
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Webhooks
patch:
summary: Update Webhook Subscription
description: ''
operationId: update-webhook-subscription
parameters:
- name: id
in: path
description: ID of the webhook subscription to update.
schema:
type: string
required: true
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used only by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
requestBody:
content:
application/json:
schema:
type: object
properties:
callback_url:
type: string
description: Destination URL for webhook deliveries (HTTPS only).
headers:
type: object
description: Custom key:value pairs to be sent as headers in every callback.
properties: {}
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"callback_url\": \"http://example.com\",\n \"created_at\": \"2019-08-24T14:15:22Z\",\n \"\
event\": \"shop.test\",\n \"headers\": {},\n \"id\": \"a47606a1-5b39-4a81-9480-c2cb738ff675\",\n \"\
updated_at\": \"2019-08-24T14:15:22Z\",\n}"
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Webhooks
/api/v2/webhooks/example:
get:
summary: Example Event
description: ''
operationId: example-event
parameters:
- name: event
in: query
description: Webhook subscription `event` type.
required: true
schema:
type: string
enum:
- shop.test
- shop.incoming_message
- shop.subscriber.opt_in
- shop.subscriber.opt_out
- shop.email_collected
default: shop.test
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used only by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"webhook_id\": \"89066f0a-eb36-4ed8-b98c-606e6dcac715\",\n \"resource_type\": \"shop\",\n\
\ \"resource_id\": \"shop_1234567abcd\",\n \"event_time\": \"2021-11-04T21:52:41.025455\",\n \"event\"\
: \"shop.incoming_message\",\n \"event_data\": {\n \"id\": \"im_1b2a005a386281c9\",\n \"subscriber_id\"\
: \"s_1234567abcd\",\n \"shop_id\": \"shop_1234567abcd\",\n \"is_opt_out\": false,\n \"shopify_customer_id\"\
: null,\n \"from_number\": \"+15555555555\",\n \"created_at\": \"2021-11-04T21:52:41.025455\",\n\
\ \"body\": \"Hello, world\"\n }\n}"
schema:
type: object
properties:
webhook_id:
type: string
example: 89066f0a-eb36-4ed8-b98c-606e6dcac715
resource_type:
type: string
example: shop
resource_id:
type: string
example: shop_1234567abcd
event_time:
type: string
example: '2021-11-04T21:52:41.025455'
event:
type: string
example: shop.incoming_message
event_data:
type: object
properties:
id:
type: string
example: im_1b2a005a386281c9
subscriber_id:
type: string
example: s_1234567abcd
shop_id:
type: string
example: shop_1234567abcd
is_opt_out:
type: boolean
example: false
default: true
shopify_customer_id: {}
from_number:
type: string
example: '+15555555555'
created_at:
type: string
example: '2021-11-04T21:52:41.025455'
body:
type: string
example: Hello, world
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Webhooks
/api/v2/keywords/{id}:
get:
summary: Get Keyword
description: Get a Keyword by its ID
operationId: get-keyword
parameters:
- name: id
in: path
description: ID of the keyword you'd like to receive.
schema:
type: string
required: true
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used *only* by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: " {\n \"created_at\": \"2021-10-01T03:17:09.306630\",\n \"id\": \"kw_31afjew824892ks\",\n\
\ \"keyword\": \"YOUROCK\",\n \"triggered_count\": 10,\n \"updated_at\": \"2021-10-01T03:17:09.306639\"\
\n }"
schema:
type: object
properties:
created_at:
type: string
example: '2021-10-01T03:17:09.306630'
id:
type: string
example: kw_31afjew824892ks
keyword:
type: string
example: YOUROCK
triggered_count:
type: integer
example: 10
default: 0
updated_at:
type: string
example: '2021-10-01T03:17:09.306639'
'404':
description: '404'
content:
application/json:
examples:
Result:
value: "{\n \"error_code\": 3001,\n \"error_message\": \"Could not find keyword matching that information\"\
,\n \"success\": false\n}"
schema:
type: object
properties:
error_code:
type: integer
example: 3001
default: 0
error_message:
type: string
example: Could not find keyword matching that information
success:
type: boolean
example: false
default: true
deprecated: false
tags:
- Keywords
/api/v2/keywords:
get:
summary: Get Keywords
description: Get a list of all active keywords for a shop.
operationId: get-keywords
parameters:
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used *only* by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"keywords\": [{\n \"created_at\": \"2021-10-01T03:17:09.306630\",\n \"id\": \"kw_31afjew824892ks\"\
,\n \"keyword\": \"YOUROCK\",\n \"triggered_count\": 10,\n \"updated_at\": \"2021-10-01T03:17:09.306639\"\
\n }]\n}"
schema:
type: object
properties:
keywords:
type: array
items:
type: object
properties:
created_at:
type: string
example: '2021-10-01T03:17:09.306630'
id:
type: string
example: kw_31afjew824892ks
keyword:
type: string
example: YOUROCK
triggered_count:
type: integer
example: 10
default: 0
updated_at:
type: string
example: '2021-10-01T03:17:09.306639'
'403':
description: '403'
content:
application/json:
examples:
Result:
value: "{\n \"error\": \"You do not have permission to do that.\"\n}"
schema:
type: object
properties:
error:
type: string
example: You do not have permission to do that.
deprecated: false
tags:
- Keywords
/api/v2/message_requests/{id}:
get:
summary: Get Message Request
description: ''
operationId: get-message-request
parameters:
- name: id
in: path
description: ID of the message request to look up.
schema:
type: string
required: true
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used *only* by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\n \"body\": \"string\",\n \"category\": \"conversational\",\n \"created_at\": \"2019-08-24T14:15:22Z\"\
,\n \"id\": \"string\",\n \"phone\": \"string\",\n \"scheduled_at\": \"2019-08-24T14:15:22Z\",\n \"\
sent_message\": {\n \"body\": \"string\",\n \"created_at\": \"2019-08-24T14:15:22Z\",\n \"credits_used\"\
: 0,\n \"id\": \"string\",\n \"media_url\": \"string\",\n \"phone\": \"string\",\n \"shop_id\"\
: \"string\",\n \"subscriber_id\": \"string\"\n },\n \"status\": \"processing\",\n \"status_code\"\
: 0,\n \"subscriber_id\": \"string\",\n \"updated_at\": \"2019-08-24T14:15:22Z\"\n}"
schema:
type: object
properties:
body:
type: string
example: string
category:
type: string
example: conversational
created_at:
type: string
example: '2019-08-24T14:15:22Z'
id:
type: string
example: string
phone:
type: string
example: string
scheduled_at:
type: string
example: '2019-08-24T14:15:22Z'
sent_message:
type: object
properties:
body:
type: string
example: string
created_at:
type: string
example: '2019-08-24T14:15:22Z'
credits_used:
type: integer
example: 0
default: 0
id:
type: string
example: string
media_url:
type: string
example: string
phone:
type: string
example: string
shop_id:
type: string
example: string
subscriber_id:
type: string
example: string
status:
type: string
example: processing
status_code:
type: integer
example: 0
default: 0
subscriber_id:
type: string
example: string
updated_at:
type: string
example: '2019-08-24T14:15:22Z'
'400':
description: '400'
content:
application/json:
examples:
Result:
value: '{}'
schema:
type: object
properties: {}
deprecated: false
tags:
- Messages
/api/v2/sent_messages/{id}:
get:
summary: Get Sent Message
description: ''
operationId: get-sent-message
parameters:
- name: id
in: path
description: ID of sent message to fetch.
schema:
type: string
required: true
- name: X-Postscript-Shop-Token
in: header
description: Shop API Token. **Required for partners**. This header should be used *only* by partners. Shops should
include their API token in the *Authorization* header.
schema:
type: string
responses:
'200':
description: '200'
content:
application/json:
examples:
Result:
value: "{\
# --- truncated at 32 KB (55 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/postscript/refs/heads/main/openapi/_original/postscript-partner-api-openapi.yml