TwinJet-DirectConnect

The TwinJet API allows for clients to submit delivery jobs directly to a courier company using the TwinJet platform.


Security

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_tokens. 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.


New Job

Endpoint https://www.twinjet.co/api/v1/jobs/ MethodPOST Content Typeapplication/json

Parameters

. .
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.

Please note In order to successfully submit an order, you must provide either:

  1. pick_address
  2. deliver_address
  3. 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.

Address Object

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.

JobItem Object

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.

Example New Job JSON Payload

            {
                "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"
                    }
                ]
            }
        

Response

If your 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.

Regarding Job Processing in TwinJet

The TwinJet API processes jobs asynchronously; meaning you may get the request_id back before TwinJet is finished creating the job.

Webhooks

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.


Cancel Job

Endpoint https://www.twinjet.co/api/v1/jobs/ MethodDELETE Content Typeapplication/json

Parameters

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.

Please note In order to successfully cancel a job, you must provide either:

  1. request_id
  2. job_id
  3. external_id
  4. 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.

Sample Cancel JSON Payload

            {
                "api_token" : "1234",
                "request_id" : "A1B2C3D4E5"
            }
        

Response

If your DELETE request passes validation, you recieve a 200 OK and a JSON status object in response (see Job Status API below).


Edit / Update Job

Endpoint https://www.twinjet.co/api/v1/jobs/ MethodPATCH Content Typeapplication/json

Parameters - Required

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.

Parameters - Editable

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.

Please note In order to successfully edit a job, you must provide either:

  1. request_id
  2. job_id
  3. external_id
  4. 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.

Response

If your PATCH request passes validation, you receive a 200 OK and an updated JSON status object in response (see Job Status API below).


Job Status

Requesting the status of a job

Endpoint https://www.twinjet.co/api/v1/status/ MethodPOST Content Typeapplication/json

Parameters

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.

Please note In order to successfully obtain a job status, you must provide either:

  1. request_id
  2. job_id
  3. external_id
  4. reference

Failing to provide one of the above will result in a 400 BAD REQUEST.

Sample Status JSON Payload

                {
                    "api_token" : "1234",
                    "request_id" : "A1B2C3D4E5"
                }
            

Response

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"
                        }
                    ]
                }
            

Status Codes

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.
51 Rejected Job has been rejected by the courier company. Not yet implemented.
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

Job history is the log of all events associated with the job.


Address Validation

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/ MethodPOST Content Typeapplication/json

Parameters

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.

Please note In order to successfully obtain a job quote, you must provide either:

  1. pick_address
  2. 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.

Sample Validate JSON Payload

               {
                    "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"
                    }
                }
            

Example Response JSON

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
                    }
                }
            

API Version History

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