Thankful’s Standard Model Spec is a framework that enables Thankful to deeply integrate your business, handling returns, missing packages, order tracking and more using custom backends.
The Standard Model delivers value immediately with small engineering asks, then improves over time with additional effort. With this framework you can spec out and plan your engineering requirements alongside the type of experience you’d like to deliver to your customers.
Each action Thankful performs has a set of endpoints that you MUST implement. Each endpoint has fields that you MUST or MAY implement. Optional fields are noted in the documentation with additional comments surrounding blocks of fields: if provided, optional fields unlock better experiences for your customers.
URLs are set and cannot be adjusted. Thankful will send a request to the URL
exactly as described. All request URLs are namespaced under /thankful/api/
.
URL parameters will always be URL-encoded according to RFC3986.
This API is versioned on an endpoint-by-endpoint basis, enabling you to upgrade
endpoints gradually. For instance, you could use both v1.0 of Get Order and
v2.0 of Return Order. It’s up to you to self-report your API version in the
X-API-Version
response header, for example:
X-API-Version: v1.0
Your server MUST send a version header with every response.
The current version is v1.0. The Standard Model follows semver, so
non-breaking changes such as adding fields and endpoints will increment the
MINOR number, e.g. v1.1
, v1.2
. Any breaking changes such as renaming fields
or removing fields will be done very rarely, but those will increment the MAJOR
number, e.g. v2.0
, v3.0
.
Thankful uses Basic authentication over HTTPS in combination with other security measures.
You can generate and expire API keys on the API Settings page.
That is enough to protect most applications.
Some companies require additional verification, so Thankful supports the following approaches. None are necessary for your security, but they optionally layer protections on top of the Basic auth HTTPS core:
To enable any action, all of the associated endpoints MUST be implemented.
Endpoint: GET /thankful/api/orders
Query parameters:
One of the above query parameters will always be included.
Example:
GET <your_api_url>/thankful/api/orders?email=bob%40example.com
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
<empty>
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
[]Order
Endpoint: POST /thankful/api/orders
Example:
POST <your_api_url>/thankful/api/orders
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
Order
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
Order
Endpoint: PATCH /thankful/api/orders/:id
Example:
PATCH <your_api_url>/thankful/api/orders/123
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
Order
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
<empty>
Endpoint: POST /thankful/api/orders/:id/returns
Example:
POST <your_api_url>/thankful/api/orders/123/returns
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
Return
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
Return
Endpoint: GET /thankful/api/customers
Query parameters:
One of the above query parameters will always be included.
Example:
GET <your_api_url>/thankful/api/customers?email=bob%40example.com
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
<empty>
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
[]Customer
Endpoint: GET /thankful/api/customers/:id
Example:
GET <your_api_url>/thankful/api/customers/123
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
<empty>
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
Customer
Endpoint: PATCH /thankful/api/customers/:id
Example:
PATCH <your_api_url>/thankful/api/customers/123
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
Customer
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
<empty>
Endpoint: POST /thankful/api/customers/:id/password_reset
Example:
POST <your_api_url>/thankful/api/customers/123/password_reset
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
<empty>
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
<empty>
Endpoint: POST /thankful/api/orders/:id/discounts
Example:
POST <your_api_url>/thankful/api/orders/123/discounts
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
Discount
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
Discount
Endpoint: PATCH /thankful/api/subscriptions/:id
Example:
PATCH <your_api_url>/thankful/api/subscriptions/123
Request:
Header:
Authentication: Basic <your_auth_token>
X-Request-ID: 9bsv0s23l8og00uph220
X-Timestamp: 2019-12-31T00:00:00Z
Content-Type: application/json
Accept: application/json
Body:
Subscription
Response:
Status: 200 OK
Header:
X-API-Version: v1.0
Content-Type: application/json
Body:
<empty>
Data structures are split into several sections to minimize the build-out based on what’s needed for the business. A certain set of fields for each data type are required for core functionality. Required fields MUST all be implemented for any endpoint which requires them. The endpoints needed for your business will depend on your tickets, and Thankful can make helpful recommendations on great places to start. See Actions for more detail on required endpoints and data-structures on an action-by-action basis.
You can opt-into more advanced features by providing additional fields, such as allowing Thankful to process returns for individual items by providing line_items, returns, and refunds information when looking up orders.
Your business can add more fields over time and Thankful will automatically adapt its workflows to use them, instantly offering customers more incredible experiences.
Each field has a name and a data type. There are core data types (int, string,
float, bool), specific formats like RFC3339_timestamp which is a string in the
form of “2019-12-31T00:00:00Z”, and other data structures like Address or
Fulfillment. Each data structure is documented in the same way. An asterisk
(*
) indicates that the field might be null or not included.
All prices use whole cents (integers). Floating point numbers or strings are never used for prices.
A street address.
{
street_1 string
street_2 string
city string
state string
country string
zip string
}
Carrier must be one of the following:
We have hundreds of carrier integrations. If you use a different carrier, let Thankful know, and we’ll provide you the identifier.
{
id string
full_name string
phones []string
emails []string
vip bool
blacklist bool
orders []Order
// For subscription companies
subscriptions []Subscription
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
{
id string
// If you give pre-generated discount codes to users
code string
// If discounts will be applied without pre-generated codes
amount int
amount_type string
created_at RFC3339_timestamp
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
Either code
OR (amount
AND amount_type
) must be defined.
A fulfillment represents a single package or shipment.
{
id string
line_item_ids []string
shipping_address Address
shipping_speed ShippingSpeed
carrier Carrier
status FulfillmentStatus
tracking_number string
tracking_url string
created_at RFC3339_timestamp
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
FulfillmentStatus is a string enum which must have one of the following values:
Line item in an order represents an individual product that was purchased.
{
product_id string
name string
price int
category *string
quantity int
photo_url string
return_eligible bool
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
{
// Required for core functionality. If an order does not require
// delivery (such as for digital products), leave shipping_address
// null
id string
order_number string
status OrderStatus
shipping_address *Address
fulfillments []Fulfillment
customer_id string
total_price int
created_at RFC3339_timestamp
// To control whether we allow cancellations beyond time-based SLAs
cancel_eligible bool
// For marketplaces with 2-sided buyer+seller transactions
seller_shipping_address *Address
seller_fulfillments []Fulfillment
// For full returns/exchange experience
line_items []LineItem
returns []Return
refunds []Refund
// For sending replacement items, packages
line_items []LineItem
reference_order_id string
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
OrderStatus is a string enum which must be one of the following depending on your type of business. It is important you only use the statuses for your business type and do not mix-and-match the ones below.
Traditional ecommerce where a store sells directly to a buyer use these statuses:
2-sided marketplaces where the seller ships directly to a buyer (i.e. there’s no review step) will use these statuses:
2-sided marketplaces that connect a buyer and a seller with a middle verification step, such as to check for authenticity, will use these statuses:
{
id string
amount int
return_id *string
discount_id *string
created_at RFC3339_timestamp
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
Exactly one return_id OR discount_id must be included. Refunds with null return_id AND discount_id are invalid. Refunds that include both return_id AND discount_id are invalid.
{
id string
total int
adjusted int
refund_id string
returned_line_item_ids []string
started_at RFC3339_timestamp
received_at *RFC3339_timestamp
return_label_urls []string
fulfillments []*Fulfillment
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
adjusted
would be lower than total
.ShippingSpeed is a string enum which must have one of the following values:
{
id string
status SubscriptionStatus
customer_id CustomerID
refunds []*Refund
per_year int
tier string
last_order_id *string
next_order_scheduled_at *RFC3339_timestamp
last_billed_at *RFC3339_timestamp
paused_until *RFC3339_timestamp
expires_at *RFC3339_timestamp
created_at RFC3339_timestamp
// For one-off data to enable functionality beyond this framework.
// You'll need to work with Thankful's deployment team to utilize any
// data provided as properties. Only string key/value pairs are
// supported.
properties {
key string
value string
}
}
SubscriptionStatus is a string enum that must be one of the following: