The TwinJet API allows for clients to submit delivery jobs directly to a courier company using the TwinJet platform.
All Requests to TwinJet are over SSL. You will be issued an api_token
that serves as your identification to the system. You are only permitted to interact with a single client per api_token
. Interactions are defined as job creation, job status, cancellation, etc. If you are an entity that requires access to multiple clients, you will be issued multiple api_token
s. Please keep your client identifiers secure. If, for any reason, you expose your api_token
in an unsecured fashion, please immediately contact the courier company that manages your TwinJet API account to request a new api_token
.
Endpoint | https://www.twinjet.co/api/v1/jobs/ | Method | POST | Content Type | application/json |
---|
Name | Type | Required | Description |
---|---|---|---|
live | Boolean | Yes | Determines if this job should be processed by TwinJet. In the future, you will be able to inspect jobs marked as false in an API request inspector. For now, make sure this is set to true | .
api_token | String | Yes | This is your api token issued by your company. This will identify you and provide authentication. |
order_contact_name | String | Yes | Name of a person the courier company can contact if there is a problem with your order. This should not be the recipient of the delivery, but rather somebody the courier can contact if something goes wrong with the fulfillment of the job. |
order_contact_phone | String | Yes | Phone number of a person the courier company can contact if there is a problem with your order. This should not be the recipient of the delivery, but rather somebody the courier can contact if something goes wrong with the fulfillment of the job. |
pick_address | Address Object (See below for fields) | No (See Footnote) | The address where the courier should make the pick up. |
deliver_address | Address Object (See below for fields) | No (See Footnote) | The address where the courier should make the delivery. |
ready_time | ISO 8601 Localized Datetime | Yes | The date and time that a job is ready for pick up. |
deliver_from_time | ISO 8601 Localized Datetime | Yes | The date and time representing the beginning of the delivery window |
deliver_to_time | ISO 8601 Localized Datetime | Yes | The date and time representing the end of the delivery window |
webhook_url | URL | No | URL to receive webhook events. |
reference | String | No | A job reference for billing purposes (If you want something the courier can use to reference your order easily, use external_id). |
service_id | Integer | No | The ID for the service level. This ID would be provided by the courier company and only used for changing the service from the default (eg: upgrading from the default "Same-Day" service to "1-Hour"). |
payment_method | Integer | No | Payment method for the delivery, options: INVOICE = 1 (no transaction at delivery) CUSTOMER PREPAID = 2 (customer pre tips) CUSTOMER CC = 4 (customer tips at delivery) CUSTOMER CASH = 6 |
order_total | Decimal | No | The order total |
delivery_fee | Decimal | No | The order delivery fee. |
tip | Decimal | No | The order tip |
job_items | Array of JobItem Objects | No | If you went to pass specific information on what the courier should pick up, you may pass an array of Jobitem objects detailed below. |
special_instructions | String | No | Any special instructions may be specified here. |
photo | Boolean | No | Requires a photo be taken before a job can be marked delivered. | .
external_id | String | No | A refrence number for the courier to use. This will be displayed to the courier. |
pick_address
deliver_address
Both pick_address
and deliver_address
When you only provide a pick_address
, TwinJet will use the client location as the delivery address. Likewise, when you provide only the delivery_address
, TwinJet will use your client location as the pick address.
Name | Type | Required | Description |
---|---|---|---|
address_name | String | No | The "Line 1" of an address. Typically the company name, or recipient name. |
street_address | String | Yes | The house number + street name. For example: 565 Ellis St |
floor | String | No | Floor/Suite Number/Apartment Number/Unit |
city | String | Yes | The city name |
state | String | Yes | The two letter USPS state abbreviation. CA; not California. |
zip_code | String | Yes | The 5 digit USPS zip code for the address. Do not pass the zip+4, 5 character limit. |
contact | String | No | A contact person located at the address. |
phone_number | String | No | A contact phone number for somebody at the address. |
special_instructions | String | No | Any address specific delivery instructions. |
Name | Type | Required | Description |
---|---|---|---|
quantity | Integer | Yes | The quantity of the job item |
description | String | No | A description of the item being picked up |
sku | String | No | A SKU/Id of the item being picked up. |
{ "live" : true, "api_token" : "1234", "order_contact_name" : "Larry Bluejeans", "order_contact_phone" : "5555555555", "pick_address" : { "address_name" : "TCB Courier", "street_address" : "565 Ellis St", "floor" : "Unit B", "city" : "San Francisco", "state" : "CA", "zip_code" : "94109", "contact" : "Larry Bluejeans", "special_instructions" : "Come right in" }, "deliver_address" : { "address_name" : "Important Office Building", "street_address" : "560 Mission St", "floor" : "13th floor", "city" : "San Francisco", "state" : "CA", "zip_code" : "94105", "contact" : "P. Pete", "special_instructions" : "Go to the messenger center" }, "ready_time" : "2014-08-04T13:54:28.630613-07:00", "deliver_from_time" : "2014-08-04T13:54:28.630613-07:00", "deliver_to_time" : "2014-08-04T14:54:28.630613-07:00", "service_id": 21, "order_total" : 20.00, "tip" : 5.00, "webhook_url" : "https://www.myawesomecompany.io/order/1234/", "job_items" : [ { "quantity" : 4, "description" : "Fried Chickens" }, { "quantity" : 1, "description" : "Coke" } ] }
POST
request passes validation, you receive the following JSON in response:
{ "request_id" : "A1B2C3D4E5" }
Name | Type | Description |
---|---|---|
request_id | String(10) | A unique identifier associated with that API request. You can the request_id to look up your job. |
The TwinJet API processes jobs asynchronously; meaning you may get the request_id
back before TwinJet is finished creating the job.
In order to better provide API consumers with up to date information about the status of jobs, API users may elect to pass an URL that TwinJet can POST to with job updates. The webhooks will send the same data structure as the job status object to the url specified.
Endpoint | https://www.twinjet.co/api/v1/jobs/ | Method | DELETE | Content Type | application/json |
---|
Name | Type | Required | Description |
---|---|---|---|
api_token | String | Yes | This is your api token issued by your company. This will identify you and provide authentication. |
request_id | String | No - See Footnote | This is the id obtained when submitting a new job. |
job_id | Integer | No - See Footnote | This is the Twinjet job id. |
external_id | String | No - See Footnote | Your external reference number. |
reference | String | No - See Footnote | A job reference for billing purposes. |
request_id
job_id
external_id
reference
Failing to provide one of the above will result in a 400 BAD REQUEST
.
Attempting to cancel a job that is already picked up and en-route to delivery will result in a 406 NOT ACCEPTABLE
and will require contacting the service vendor to cancel.
{ "api_token" : "1234", "request_id" : "A1B2C3D4E5" }
If your DELETE
request passes validation, you recieve a 200 OK
and a JSON status object in response (see Job Status API below).
Endpoint | https://www.twinjet.co/api/v1/jobs/ | Method | PATCH | Content Type | application/json |
---|
Name | Type | Required | Description |
---|---|---|---|
api_token | String | Yes | This is your api token issued by your company. This will identify you and provide authentication. |
request_id | String | No - See Footnote | This is the id obtained when submitting a new job. |
job_id | Integer | No - See Footnote | This is the Twinjet job id. |
external_id | String | No - See Footnote | Your external reference number. |
reference | String | No - See Footnote | A job reference for billing purposes. |
Name | Type | Description |
---|---|---|
order_contact_name | String | Name of a person the courier company can contact if there is a problem with your order. This should not be the recipient of the delivery, but rather somebody the courier can contact if something goes wrong with the fulfillment of the job. |
order_contact_phone | String | Phone number of a person the courier company can contact if there is a problem with your order. This should not be the recipient of the delivery, but rather somebody the courier can contact if something goes wrong with the fulfillment of the job. |
pick_address | Address Object (See below for fields) | The address where the courier should make the pick up. |
deliver_address | Address Object (See below for fields) | The address where the courier should make the delivery. |
ready_time | ISO 8601 Localized Datetime | The date and time that a job is ready for pick up. |
deliver_from_time | ISO 8601 Localized Datetime | The date and time representing the beginning of the delivery window |
deliver_to_time | ISO 8601 Localized Datetime | The date and time representing the end of the delivery window |
webhook_url | URL | URL to receive webhook events. |
service_id | Integer | The ID for the service level. This ID would be provided by the courier company and only used for changing the service from the default (eg: upgrading from the default "Same-Day" service to "1-Hour"). |
payment_method | Integer | Payment method for the delivery, options: INVOICE = 1 (no transaction at delivery) CUSTOMER PREPAID = 2 (customer pre tips) CUSTOMER CC = 4 (customer tips at delivery) CUSTOMER CASH = 6 |
order_total | Decimal | The order total |
delivery_fee | Decimal | The order delivery fee. |
tip | Decimal | The order tip |
job_items | Array of JobItem Objects | If you went to pass specific information on what the courier should pick up, you may pass an array of JobItem objects detailed below. |
special_instructions | String | Any special instructions may be specified here. |
request_id
job_id
external_id
reference
Failing to provide one of the above will result in a 400 BAD REQUEST
.
Attempting to edit a job that is already picked up and en-route to delivery will result in a 406 NOT ACCEPTABLE
and will require contacting the service vendor to update.
If your PATCH
request passes validation, you receive a 200 OK
and an updated JSON status object in response (see Job Status API below).
Endpoint | https://www.twinjet.co/api/v1/status/ | Method | POST | Content Type | application/json |
---|
Name | Type | Required | Description |
---|---|---|---|
api_token | String | Yes | This is your api token issued by your company. This will identify you and provide authentication. |
request_id | String | No - See Footnote | This is the id obtained when submitting a new job. |
job_id | Integer | No - See Footnote | This is the Twinjet job id. |
external_id | String | No - See Footnote | Your external refrence number. |
reference | String | No - See Footnote | A job reference for billing purposes. |
request_id
job_id
external_id
reference
Failing to provide one of the above will result in a 400 BAD REQUEST
.
{ "api_token" : "1234", "request_id" : "A1B2C3D4E5" }
If your POST
request passes validation, you receive the following JSON in response:
{ "job_info": { "job_id": 5265, "reference": "", "request_id": "A1B2C3D4E5", "courier": "411 Billy Bikeracer", "user": "billybiker", "request_id": "MFY93TC1DL" }, "job_locations": [ { "date": "2015-10-15T04:16:06.183194+00:00", "lat": "37.7802841389", "lng": "-122.433100019", "user": "billybiker", "courier": "411 Billy Bikeracer (TCB Courier)" }, { "date": "2015-10-15T04:16:14.734744+00:00", "lat": "37.7853769431", "lng": "-122.433023193", "user": "billybiker", "courier": "411 Billy Bikeracer (TCB Courier)" } ], "current_status": { "last_location": [ "37.7853769431", "-122.433023193" ], "status_code": 62, "status_string": "delivered", "courier_name": "411 Billy Bikeracer", "remarks": "", "status_time": "2015-10-17T00:26:50.638581" }, "job_history": [ { "date": "2015-10-15T04:05:14.995373+00:00", "log": "Job was created via the TwinJet API v1.", "user": null }, { "date": "2015-10-15T04:15:59.656868+00:00", "log": "Job was assigned to 411 Billy Bikeracer.", "courier": "411 Billy Bikeracer (TCB Courier)", "user": "billybiker" }, { "date": "2015-10-15T04:16:05.270068+00:00", "log": "Job was marked as picked up.", "courier": "411 Billy Bikeracer (TCB Courier)", "user": "billybiker" }, { "date": "2015-10-15T04:24:23.561137+00:00", "log": "Job was marked as completed.", "courier": "411 Billy Bikeracer (TCB Courier)", "user": "billybiker" } ] }
Code | String | Notes |
---|---|---|
30 | Error | Server Error. |
40 | Processing | Job has been received and is processing. |
50 | Accepted | Job has been accepted and successfully created. You will now have access to the job_id . |
52 | Cancelled | Job has been cancelled. |
53 | Order Not Ready | Job pick up was attempted, but the order was not ready. |
60 | Dispatched | Job has been assigned to courier. |
61 | Picked Up | Job has been picked up by courier. |
62 | Delivered | Job has been delivered by courier. |
63 | Undeliverable | Job delivery was unsuccessfully attempted by courier. Additional information will be logged. |
Job history is the log of all events associated with the job.
Validates an address within a delivery zone and returns a price quote and estimated pickup and delivery times along with the available delivery zone in GeoJSON format.
Endpoint | https://www.twinjet.co/api/v1/validate/ | Method | POST | Content Type | application/json |
---|
Name | Type | Required | Description |
---|---|---|---|
api_token | String | Yes | This is your api token issued by your company. This will identify you and provide authentication. |
pick_address | Address Object (See above for fields) | No (See Footnote) | The address where the courier should make the pick up. |
deliver_address | Address Object (See above for fields) | No (See Footnote) | The address where the courier should make the delivery. |
pick_address
deliver_address
Failing to provide one of the above will result in a 400 BAD REQUEST
.
If there is no pick_address
or deliver_address
TwinJet will default to the api profile's default address.
{ "api_token" : "1234", "pick_address" : { "address_name" : "TCB Courier", "street_address" : "565 Ellis St", "floor" : "Unit B", "city" : "San Francisco", "state" : "CA", "zip_code" : "94109", "contact" : "Larry Bluejeans", "special_instructions" : "Come right in" }, "deliver_address" : { "address_name" : "Important Office Building", "street_address" : "560 Mission St", "floor" : "13th floor", "city" : "San Francisco", "state" : "CA", "zip_code" : "94105", "contact" : "P. Pete", "special_instructions" : "Go to the messenger room" } }
If your POST
request passes validation, and is within the available delivery zone you receive the following JSON in response along with the delivery zone in GeoJSON format:
{ "pick_address": { "address": "565 Ellis Street", "city": "San Francisco", "state": "CA", "floor": "Unit B", "zip": "94109", "lat": 37.7843461905875, "lng": -122.415412005654 }, "drop_address": { "address": "560 Mission Street", "city": "San Francisco", "state": "CA", "floor": "13th floor", "zip": "94105", "lat": 37.7888061913173, "lng": -122.399442005392 }, "pickup_eta": "2016-01-22T17:53:40.730-08:00", "price": "8.00", "delivery_eta": "2016-01-22T18:00:54.508-08:00" }
If your POST
request passes validation, but is outside the available delivery zone you receive the following JSON in response along with the delivery zone in GeoJSON format:
{ "errors": [ { "pick_address": "Outside of available delivery area" } ], "pick_address": { "address": "544 19th Avenue", "city": "San Francisco", "state": "CA", "floor": "Unit B", "zip": "94121", "lat": 37.7776461894887, "lng": -122.477902006678 }, "drop_address": { "address": "560 Mission Street", "city": "San Francisco", "state": "CA", "floor": "13th floor", "zip": "94105", "lat": 37.7888061913173, "lng": -122.399442005392 } }
0.8 December 29, 2015
0.7.8 October 15, 2015
0.7.7 August 23, 2015
0.7.6 June 23, 2015
0.7.5 June 3, 2015
0.7.2 December 18, 2014
0.7 October 6, 2014
0.6 August 7, 2014
0.5 August 5, 2014