This section includes expanded definitions of the request and response bodies for the Custom Store /events
endpoint.
Your web endpoint should return a response that indicates what the result of each notification was. The result of any event that your web endpoint does not recognize is still considered a success. This is so that ShipStation can continue adding new events without causing errors in stores that do not support them.
ShipStation will contact the web endpoint when certain actions are taken so your system can be notified of those events.
Each notification could contain a number of different events, but it is not necessary for your web endpoint to process every event type.
We recommend that all Custom Store integrations listen for the fulfilled
event so that you can update your cart or marketplace with tracking info from the shipped order.
POST /events HTTP/1.1
Host: api.my-store.com
Authorization: Basic ZGVtbzpwQDU1dzByZA==
Content-Type: application/json
Accept: application/json
{
"events": [
{
"event_id": "evt_w6W9yp8sPJ9RGb9fY4T",
"type": "fulfilled",
"occurred_at": "2020-01-18T05:13:14.000Z",
"shipment_id": "shp_X735ioRGb9fQqkldA9pz2",
"tracking_number": "1Z918478194858101",
"carrier_code": "fedex",
"service_code": "fedex_ground",
"orders": [
{
"order_id": "QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp",
"items": [
{
"item_id": "9TWjnieMw6-89ypRCfY4XBGb-QsPJ9",
"quantity": 3
}
]
},
{
"order_id": "9374jksd-Dkso Dkw-snieMw68",
"items": [
{
"item_id": "op29ypfY4-19923k-PJ9oi81m",
"quantity": 1
},
{
"item_id": "u7msh2ETxpUv-2751XFqqAzpem6",
"quantity": 1
}
]
}
]
}
]
}
curl -iX POST https://api.my-store.com/events \
-H 'Authorization: Basic ZGVtbzpwQDU1dzByZA==' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-d '{
"events": [
{
"event_id": "evt_w6W9yp8sPJ9RGb9fY4T",
"type": "fulfilled",
"occurred_at": "2020-01-18T05:13:14.000Z",
"shipment_id": "shp_X735ioRGb9fQqkldA9pz2",
"tracking_number": "1Z918478194858101",
"carrier_code": "fedex",
"service_code": "fedex_ground",
"orders": [
{
"order_id": "QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp",
"items": [
{
"item_id": "9TWjnieMw6-89ypRCfY4XBGb-QsPJ9",
"quantity": 3
}
]
},
{
"order_id": "9374jksd-Dkso Dkw-snieMw68",
"items": [
{
"item_id": "op29ypfY4-19923k-PJ9oi81m",
"quantity": 1
},
{
"item_id": "u7msh2ETxpUv-2751XFqqAzpem6",
"quantity": 1
}
]
}
]
}
]
}'
$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Host", "api.my-store.com")
$headers.Add("Authorization", "Basic ZGVtbzpwQDU1dzByZA==")
$headers.Add("Content-Type", "application/json")
$headers.Add("Accept", "application/json")
$body = "{`n `"events`": [`n {`n `"event_id`": `"evt_w6W9yp8sPJ9RGb9fY4T`",`n `"type`": `"fulfilled`",`n `"occurred_at`": `"2020-01-18T05:13:14.000Z`",`n `"shipment_id`": `"shp_X735ioRGb9fQqkldA9pz2`",`n `"tracking_number`": `"1Z918478194858101`",`n `"carrier_code`": `"fedex`",`n `"service_code`": `"fedex_ground`",`n `"orders`": [`n {`n `"order_id`": `"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp`",`n `"items`": [`n {`n `"item_id`": `"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9`",`n `"quantity`": 3`n }`n ]`n },`n {`n `"order_id`": `"9374jksd-Dkso Dkw-snieMw68`",`n `"items`": [`n {`n `"item_id`": `"op29ypfY4-19923k-PJ9oi81m`",`n `"quantity`": 1`n },`n {`n `"item_id`": `"u7msh2ETxpUv-2751XFqqAzpem6`",`n `"quantity`": 1`n }`n ]`n }`n ]`n }`n ]`n}"
$response = Invoke-RestMethod 'https://api.my-store.com/events' -Method 'POST' -Headers $headers -Body $body
$response | ConvertTo-Json
var myHeaders = new Headers();
myHeaders.append("Host", "api.my-store.com");
myHeaders.append("Authorization", "Basic ZGVtbzpwQDU1dzByZA==");
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Accept", "application/json");
var raw = JSON.stringify({"events":[{"event_id":"evt_w6W9yp8sPJ9RGb9fY4T","type":"fulfilled","occurred_at":"2020-01-18T05:13:14.000Z","shipment_id":"shp_X735ioRGb9fQqkldA9pz2","tracking_number":"1Z918478194858101","carrier_code":"fedex","service_code":"fedex_ground","orders":[{"order_id":"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp","items":[{"item_id":"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9","quantity":3}]},{"order_id":"9374jksd-Dkso Dkw-snieMw68","items":[{"item_id":"op29ypfY4-19923k-PJ9oi81m","quantity":1},{"item_id":"u7msh2ETxpUv-2751XFqqAzpem6","quantity":1}]}]}]});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
fetch("https://api.my-store.com/events", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error));
var request = require('request');
var options = {
'method': 'POST',
'url': 'https://api.my-store.com/events',
'headers': {
'Host': 'api.my-store.com',
'Authorization': 'Basic ZGVtbzpwQDU1dzByZA==',
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({"events":[{"event_id":"evt_w6W9yp8sPJ9RGb9fY4T","type":"fulfilled","occurred_at":"2020-01-18T05:13:14.000Z","shipment_id":"shp_X735ioRGb9fQqkldA9pz2","tracking_number":"1Z918478194858101","carrier_code":"fedex","service_code":"fedex_ground","orders":[{"order_id":"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp","items":[{"item_id":"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9","quantity":3}]},{"order_id":"9374jksd-Dkso Dkw-snieMw68","items":[{"item_id":"op29ypfY4-19923k-PJ9oi81m","quantity":1},{"item_id":"u7msh2ETxpUv-2751XFqqAzpem6","quantity":1}]}]}]})
};
request(options, function (error, response) {
if (error) throw new Error(error);
console.log(response.body);
});
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.my-store.com/events",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS =>"{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}",
CURLOPT_HTTPHEADER => array(
"Host: api.my-store.com",
"Authorization: Basic ZGVtbzpwQDU1dzByZA==",
"Content-Type: application/json",
"Accept: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
import requests
url = "https://api.my-store.com/events"
payload = "{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}"
headers = {
'Host': 'api.my-store.com',
'Authorization': 'Basic ZGVtbzpwQDU1dzByZA==',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
response = requests.request("POST", url, headers=headers, data = payload)
print(response.text.encode('utf8'))
require "uri"
require "net/http"
url = URI("https://api.my-store.com/events")
https = Net::HTTP.new(url.host, url.port);
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Host"] = "api.my-store.com"
request["Authorization"] = "Basic ZGVtbzpwQDU1dzByZA=="
request["Content-Type"] = "application/json"
request["Accept"] = "application/json"
request.body = "{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}"
response = https.request(request)
puts response.read_body
var client = new RestClient("https://api.my-store.com/events");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Host", "api.my-store.com");
request.AddHeader("Authorization", "Basic ZGVtbzpwQDU1dzByZA==");
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddParameter("application/json", "{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}");
Request request = new Request.Builder()
.url("https://api.my-store.com/events")
.method("POST", body)
.addHeader("Host", "api.my-store.com")
.addHeader("Authorization", "Basic ZGVtbzpwQDU1dzByZA==")
.addHeader("Content-Type", "application/json")
.addHeader("Accept", "application/json")
.build();
Response response = client.newCall(request).execute();
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://api.my-store.com/events"
method := "POST"
payload := strings.NewReader("{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}")
client := &http.Client {
}
req, err := http.NewRequest(method, url, payload)
if err != nil {
fmt.Println(err)
}
req.Header.Add("Host", "api.my-store.com")
req.Header.Add("Authorization", "Basic ZGVtbzpwQDU1dzByZA==")
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
res, err := client.Do(req)
defer res.Body.Close()
body, err := ioutil.ReadAll(res.Body)
fmt.Println(string(body))
}
#import <Foundation/Foundation.h>
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.my-store.com/events"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
NSDictionary *headers = @{
@"Host": @"api.my-store.com",
@"Authorization": @"Basic ZGVtbzpwQDU1dzByZA==",
@"Content-Type": @"application/json",
@"Accept": @"application/json"
};
[request setAllHTTPHeaderFields:headers];
NSData *postData = [[NSData alloc] initWithData:[@"{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}" dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postData];
[request setHTTPMethod:@"POST"];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSError *parseError = nil;
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
NSLog(@"%@",responseDictionary);
dispatch_semaphore_signal(sema);
}
}];
[dataTask resume];
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
import Foundation
var semaphore = DispatchSemaphore (value: 0)
let parameters = "{\n \"events\": [\n {\n \"event_id\": \"evt_w6W9yp8sPJ9RGb9fY4T\",\n \"type\": \"fulfilled\",\n \"occurred_at\": \"2020-01-18T05:13:14.000Z\",\n \"shipment_id\": \"shp_X735ioRGb9fQqkldA9pz2\",\n \"tracking_number\": \"1Z918478194858101\",\n \"carrier_code\": \"fedex\",\n \"service_code\": \"fedex_ground\",\n \"orders\": [\n {\n \"order_id\": \"QsPJ9R-CfY4 BjnieMw68-Gb9TW9yp\",\n \"items\": [\n {\n \"item_id\": \"9TWjnieMw6-89ypRCfY4XBGb-QsPJ9\",\n \"quantity\": 3\n }\n ]\n },\n {\n \"order_id\": \"9374jksd-Dkso Dkw-snieMw68\",\n \"items\": [\n {\n \"item_id\": \"op29ypfY4-19923k-PJ9oi81m\",\n \"quantity\": 1\n },\n {\n \"item_id\": \"u7msh2ETxpUv-2751XFqqAzpem6\",\n \"quantity\": 1\n }\n ]\n }\n ]\n }\n ]\n}"
let postData = parameters.data(using: .utf8)
var request = URLRequest(url: URL(string: "https://api.my-store.com/events")!,timeoutInterval: Double.infinity)
request.addValue("api.my-store.com", forHTTPHeaderField: "Host")
request.addValue("Basic ZGVtbzpwQDU1dzByZA==", forHTTPHeaderField: "Authorization")
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
request.httpMethod = "POST"
request.httpBody = postData
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
print(String(data: data, encoding: .utf8)!)
semaphore.signal()
}
task.resume()
semaphore.wait()
The Custom Store implementation can simply respond with an HTTP 200 or 204 response to indicate that the events were received successfully. No response body is necessary.
Some Custom Store implementations may wish to indicate a partial success. For example, some of the events were received successfully, but others were not and should be re-sent again later. In this case the API should respond with an HTTP status of 207, and the body should indicate the status of each event.