API Docs

Shipments

Once a brigade member has collected enough waste, they will want to ship it to us for processing.

For most kinds of waste, it is usually satisfactory to collect the waste in a cardboard box, tape the box down when full, and ship it through the regular postal service or parcel services.

Most collection programs offer shipping that is free to brigade members. To utilize this offer, brigade members need to acquire a shipping label from us that contains pre-paid postage, and ship the box with that label.

We call each box shipped to us this way a shipment.

Most collection programs also award points in connection with the amount of waste sent in for brigade members to spend towards charitable goals (or the school's foundation in the case of schools).

Tracking number, duplicate shipments

The label contains a unique tracking number that helps clearly identify that particular shipment for all parties involved: the brigade member sending the shipment, the postal or parcel service carrying the shipment, and us and our warehouses and processing facilities receiving and processing the shipment.

If a brigade member reuses a tracking number (e.g. by photocopying or reprinting a label and sending in multiple shipments with it), it makes unique shipment identification impossible. Because this makes billing and reporting between all parties more difficult, we discourage brigade members from doing this by not awarding points for such duplicate shipments. To help users adhere to this, we provide features that make it easy for brigade members to avoid accidentally reusing shipping labels.

Outstanding shipments

To be able to plan for the amount of waste we receive for brigades, we decided to limit the number of shipments we allow to be "in-flight", that is, the shipments brigade members indicated they will send us, but we haven't received and processed yet. We call these "in-flight" shipments outstanding shipments. (In contrast, shipments we received and processed we call received shipments.)

In order to do this, whenever a brigade member requests a label from us, we also consider it to be a promise of eventually sending in a shipment with that shipping label - to indicate this, when we issue a label we also immediately register an outstanding shipment for the brigade member, which is visible in their list of shipments.

In fact, in our API parlance the user is not even requesting a label - they are creating a shipment instead.

Non-compliant shipments

One of the tasks of our warehouses is to sort received waste into bulk containers by waste type, for efficient shipping to and batch processing at our processing facilities.

For this, they group (the as of yet unopened) incoming shipments by contents based on the brigade indicated on our shipping label, then open each individual shipment and transfer the contents into the bulk container, while also measuring and registering the unpackaged weight of each individual shipment.

If therefore a shipment contains something else than what is accepted by the brigade indicated on the shipping label, the warehouse will have to spend extra effort to repackage and relabel that shipment and send it back to sorting again to get it to the right processing facility. Because this reduces efficiency, we discourage brigade members from doing this by not awarding points for these non-compliant shipments.

Supplies, shipping options

A few collection programs offer optional supplies (e.g. special boxes, bags, liners) that brigade members can request to be delivered to them to make collecting and shipping waste for that program more practical (e.g. to prevent powder-like or liquid-containing waste from seeping out of the box during shipping and soiling the surroundings, or collection boxes with divided compartments for collecting glass bottles, etc.). We call these collection supplies. (Yet a few other programs offer labels preprinted by us.)

These supplies have to be delivered offline (e.g. through the postal or parcel services), therefore a downloadable label is not issued when requesting supplies. However, collection programs that offer supplies usually still also offer downloadable labels, and allow the user to choose between these shipping options when creating a new shipment. This is why available shipping options are shown in the detailed Brigade info, and why creating a new shipment requires a shipping_option_id to be specified - a brigade_id alone would not be sufficient to unambiguously identify what is being requested in the case of brigades with multiple shipping options.

Create a new shipment

Create a new shipment. (For rationale see the introductory section above: Shipments.)

Scope: create_shipment

Request

POST https://api.terracycle.com/en-US/v2/shipments/:shipping_option_id
Request parameters
parameter description
:shipping_option_id the (numeric) ID of the shipping option listed in the shipping_options array of the brigade (see section detailed Brigade info for details)
access_token the access_token acquired through OAuth
Example
curl \
  -d 'access_token=acce55acce55acce55acce55acce55acce55acce55acce55acce55acce55acce' \
  https://api.terracycle.com/en-US/v2/shipments/5

Response

Error - unknown shipping_option_id

The specified shipping_option_id does not exist in our system.

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipping-option-not-found"
}
Error - user is not member of brigade

The user requesting the shipment is not a member of the brigade the shipping_option_id belongs to.

Please make sure you design your application flow so that a user is joined to a brigade and has membership status active before requesting a shipment for any shipping options under that brigade. (But as we do not show shipping options for brigades the user is not a member of, this is more likely a programming error of taking the shipping_option_id from the wrong variable, or, less likely, the user might have left the brigade on another device in the meantime, behind the backs of your application, or the administrators of the brigade have changed the shipping options in the brigade since your application retrieved them.)

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "user-is-not-member-of-brigade"
}
Error - user has too many outstanding shipments in brigade

The user has too many outstanding shipments in the brigade the shipping_option_id belongs to.

The user is not currently allowed to create any more shipments for this brigade. They should first reduce the number of their outstanding shipments for this brigade by sending in some of those shipments.

This does not influence the user's ability to create shipments in other brigades.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "user-has-too-many-outstanding-shipments-in-brigade"
}
Error - generic

An unknown/unspecified error occurred during the creation of the shipment. Please ask the user to try again later, and if it still doesn't work, turn to Customer Support.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "unknown"
}
Accepted - instant downloadable label

The shipment creation request was accepted. The user requested a shipping label that can be generated automatically. It is being generated, and will be available shortly for download, or an error will be returned online.

Please display the returned message to the user as a progress message (it usually contains information relevant to the user waiting, e.g. estimated time to wait, etc.) together with a generic "waiting for progress/processing" visual indication to the user. Then start waiting for a shipping label as described below.

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
{
  "message": "Please hold while your label is being created."
  "uuid": "efc9b844-2436-4c70-84d6-506f5d6c4246"
}
Accepted - labels or collection supplies delivered later

The shipment creation request was accepted. Due to the nature of the business processes for the requested item, the user will receive status updates (including notification about potential errors) in email, and the requested item(s) will similarly be delivered offline (outside the current system - e.g. by email, by postal mail, parcel service, etc.).

Please display the returned message to the user, as it contains information relevant to the user in connection with the type of request just made.

HTTP/1.1 202 Accepted
Content-Type: application/json; charset=utf-8
{
  "message": "Your order has been received! Supplies will ship within 3 business days UPS Ground. You will receive an email confirmation and the outbound UPS tracking number for your request."
}

Waiting for a shipping label

When the user requests a new shipment to be created, their request gets queued in our system for processing on a first-come-first-served basis. Depending on how many other such requests are in our system, it could take some time for it to get processed.

So the user has to wait.

We offer the following mechanism to notify your application of completion.

Postback

If you set the postback_url in your application settings, our system will send a POST HTTP request to that URL whenever a shipment has completed processing (either successfully or with an error). The POST request will provide detailed information on the shipment.

For your convenience the POST request will provide the same detailed information both in the query string and in the HTTP POST body, so you can parse it from whichever is more convenient for you.

Success/Error

If your system has successfully processed the postback, your system should return a HTTP response body containing the following string literal: postback accepted

Example: parameters in postback URL query string

Our POST request will have a query string consisting of all the fields of the shipment as it would be returned by the Get Shipment call (see Get shipment below), plus the following field:

parameter description
account_uuid the uuid of the user who requested the shipment

Assuming your application's postback URL is set to http://httpbin.org/post, our system will send the POST request to an URL like this:

http://httpbin.org/post?uuid=f29e7a0c-d288-4ca6-ab35-c348a2a5cf0f&created_at=2014-01-03T08%3A40%3A55Z&updated_at=2014-01-03T08%3A41%3A04Z&brigade_id=142&shipping_option_id=143&status=outstanding&tracking_number=1Z1AR8610392215184&label_available=true&account_uuid=7562f6b79318420ae5550ab82c20bbbc1f22b9f4dc512e159204a6c5e63920d7
Example: parameters in JSON in postback body

Our POST request will have a JSON body that contains the shipment as it would be returned by the Get Shipment call, plus a skeleton account object which, for privacy reasons, is only showing the uuid attribute. (We do not want to send any account information in the postback since the postback can happen over unencrypted HTTP and is therefore prone to eavesdropping, it could be hijacked by DNS spoofing, etc.)

{
  "shipment": {
    "created_at": "2014-01-03T08:40:55Z",
    "status": "outstanding",
    "uuid": "f29e7a0c-d288-4ca6-ab35-c348a2a5cf0f",
    "updated_at": "2014-01-03T08:41:04Z",
    "brigade_id": 142,
    "label_available": true,
    "shipping_option_id": 143,
    "tracking_number": "1Z1AR8610392215184"
  },
  "account": {
    "uuid": "7562f6b79318420ae5550ab82c20bbbc1f22b9f4dc512e159204a6c5e63920d7"
  }
}

Get shipment

Get a single shipment specified by its uuid. The response contains exactly the same information in the same fields as a single entry in the Shipment List.

Scope: get_shipment

Request

GET https://api.terracycle.com/en-US/v2/shipments/:shipment_uuid
Request parameters
parameter description
:shipment_uuid the shipment's UUID.
access_token the access_token acquired through OAuth
Example
curl -G \
  -d 'access_token=acce55acce55acce55acce55acce55acce55acce55acce55acce55acce55acce' \
  https://api.terracycle.com/en-US/v2/shipments/8ed8756d-79ba-40d9-a5bf-55153674ddab

Response

For a full list of possible responses (and errors) please see the Shipment List endpoint below.

Error - Shipment not found

The shipment with the requested uuid does not exist.

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-not-found"
}
Success - Shipment found
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "shipment": {
    "uuid": "9364e859-9456-4fdf-98ff-b7fec50e8e27",
    "created_at": "2007-04-05T12:30-02:00",
    "updated_at": "2007-04-05T12:35-02:00",
    "brigade_id": 124,
    "shipping_option_id": 39,
    "status": "received",
    "tracking_number": "1Z1AR8610398617588",
    "received_at" : "2007-04-05T12:35-02:00",
    "waste_collected_qty": 123.456,
    "waste_collected_unit": "lbs",
    "points_earned": 100
  }
}

List shipments

List shipments of the user.

Can be filtered by: status (outstanding/received), brigade, date range, tracking numbers.

Scope: list_shipments

Request

GET https://api.terracycle.com/en-US/v2/shipments
Request parameters
parameter description
brigade_ids (optional) only show shipments for the brigade(s) with these IDs (shown in Get Brigades list)
format is comma-separated list of IDs, e.g.: 1,3,7
shipment_uuids (optional) only show shipments with these UUIDs
format is comma-separated list of shipment UUIDs, e.g.: 79de35da-416b-4cd0-b588-cfefc856c4e5,3d2c1fd1-00ff-4880-993b-9a1f7c9d8b4d,362e743d-0da8-4388-8317-8591d79e8fed
tracking_numbers (optional) only show shipments having one of the provided tracking numbers
format is comma-separated list of tracking numbers, e.g.: 1Z1AR8610398617588,1Z1AR8610398617589,1Z1AR8610398617590
status (optional) outstanding - only show outstanding shipments
received - only show received shipments
created_on_or_after (optional) only show shipments that were created on or after the given timestamp (ISO8601)
created_before (optional) only show shipments that were created before the given timestamp (ISO8601)
updated_on_or_after (optional) only show shipments where the last change/update happened on or after the given timestamp (ISO8601)
updated_before (optional) only show shipments where the last change/update happened before the given timestamp (ISO8601)
access_token the access_token acquired through OAuth
 Example
curl -G \
  -d 'access_token=acce55acce55acce55acce55acce55acce55acce55acce55acce55acce55acce' \
  https://api.terracycle.com/en-US/v2/shipments

Response

NOTE: Comments introduced with the character # below will not be part of the actual response emitted by our system - they are only included in this example for documentation purposes.

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "shipments": [
    { # a shipment waiting for processing on our end
      "uuid": "48ff3ae9-54ed-4c66-8110-d0c8a542b4d4",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:30-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "requested",
    },
    { # a shipment that encountered an error during processing
      "uuid": "8d1f71c8-0e9e-4cac-9a21-617b94542095",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:31-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "error",
      "message": "The postal code 967782202 is invalid for NM United States."
    },
    { # the shipping label can now be downloaded
      "uuid": "e2c41e84-00f3-4a4d-8e25-7bff8d583a67",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:32-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "outstanding",
      "tracking_number": "1Z1AR8610398617588",
      "label_available": true
    },
    { # shipping label expired (it is no longer available for download);
      # we are now waiting to receive the shipment
      "uuid": "6bacdc23-1c08-466c-a7e0-e305104a3b7e",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:33-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "outstanding",
      "tracking_number": "1Z1AR8610398617588",
    },
    { # an offline shipment - a label is not available to download
      "uuid": "ea99fe4a-93c9-4a2b-bcad-e287cf3eae20",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:34-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "outstanding",
      "tracking_number": "1Z1AR8610398617588"
    },
    { # a received shipment with no issues
      "uuid": "9364e859-9456-4fdf-98ff-b7fec50e8e27",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:35-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "received",
      "tracking_number": "1Z1AR8610398617588",
      "received_at" : "2007-04-05T12:35-02:00",
      "waste_collected_qty": 1234,
      "waste_collected_unit": "waste_units",
      "points_earned": 100
    },
    { # a received shipment with no issues for a weight-based brigade
      "uuid": "9364e859-9456-4fdf-98ff-b7fec50e8e27",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:35-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "received",
      "tracking_number": "1Z1AR8610398617588",
      "received_at" : "2007-04-05T12:35-02:00",
      "waste_collected_qty": 123.456,
      "waste_collected_unit": "lbs",
      "points_earned": 100
    },
    { # a received shipment that is a duplicate
      "uuid": "0247176c-fd9b-4f5a-930b-f6418449701d",
      "created_at": "2007-04-05T12:30-02:00",
      "updated_at": "2007-04-05T12:36-02:00",
      "brigade_id": 124,
      "shipping_option_id": 39,
      "status": "received",
      "tracking_number": "1Z1AR8610398617588",
      "received_at" : "2007-04-05T12:36-02:00",
      "waste_collected_qty": 1234,
      "waste_collected_unit": "waste_units",
      "points_earned": 0, # no points since the shipment has an issue
      "error_flags": "duplicate"
      "message": "Duplicate label"
    }
  ]
}
field description
uuid this is the unique identifier of the shipment within our online/web system (if you need an identifier known externally, use the tracking number - see below)
created_at ISO 8601 timestamp of when the shipment was created by the user
updated_at ISO 8601 timestamp of the last change/update happened
status requested - the user requested us to create a new shipment, and the shipment is waiting for processing on our side
error - we attempted to create the shipment for the user, but an error prevented us from doing so; the error is shown in the message field; in most cases the error is due to an icomplete or invalid address, in which case the user should fix their address based on the error message before requesting a new shipment; this shipment is invalid and cannot be sent in, so shipping labels were not issued for this shipment
outstanding - the shipment was successfully created, shipping label(s) have been issued and delivered offline or made available online (see section Create a new shipment above), and we are now waiting for the user to send in this shipment
received - we received and processed the shipment; results are indicated in other fields
brigade_id ID of brigade the shipment was created for
shipping_option_id ID of the shipping option the shipment was created for (see section shipping options for details)
tracking_number (only present for shipments with status outstanding or received)
this is the tracking number that is on the shipping label to identify this shipment between our system and the system of the postal/parcel service
label_available (only present if the shipment has a downloadable label and that label has not expired yet)
if this flag is present and true, then a label is available for download - see Retrieve a shipping label below.
received_at (only present for shipments with status received)
ISO 8601 timestamp of when the shipment was received by us
waste_collected_qty
waste_collected_unit
(only present for shipments with status received)
our measurement of the amount of waste sent in in this shipment
waste_collected_unit:
waste_units - if the brigade is based on the number of units of waste (in which case waste_collected_qty will be an integer), or
lbs/g/kg (or another unit of measurement) respectively if the brigade is based on the weight (or another physical measurement) of the waste (in which case waste_collected_qty will be a number with a decimal point)
points_earned (only present for shipments with status received)
the points we awarded for the shipment, based on the weight and/or units collected
error_flags (only present for shipments with status received and only if the shipment has an issue; currently contains only one flag, but prepare your system for a number of comma-separated identifiers)
duplicate - duplicate shipment (the shipping label this shipment was sent in with was already used before for another shipment)
message free-form human-readable message containing information about the shipment

Retrieve a shipping label

This will return the requested shipping label (if available) in the form of a 302 Found response with the URL of the label image in the Location header and the same URL in JSON in the response body; or give an error response.

Shipping labels are available for download for a certain number of days (currently 90 on this server), after which they expire and will no longer be returned by this call and also their flag label_available will be removed from the list returned by List shipments.

Scope: get_shipping_label

Request

GET https://api.terracycle.com/en-US/v2/shipments/:shipment_uuid/label
Request parameters
parameter description
:shipment_uuid the uuid of the shipment (as was listed in List shipments)
access_token the access_token acquired through OAuth
 Example
curl -G \
  -d 'access_token=acce55acce55acce55acce55acce55acce55acce55acce55acce55acce55acce' \
  https://api.terracycle.com/en-US/v2/shipments/8ed8756d-79ba-40d9-a5bf-55153674ddab/label

Response

Error - not found

The specified shipment_uuid could not be found in our database.

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-not-found"
}
Error - does not belong to user

The specified shipment_uuid was found in our database, but the shipment does not belong to the current user.

HTTP/1.1 403 Forbidden
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-does-not-belong-to-user"
}
Error - no downloadable label

The shipment was found and belongs to the user, but the shipment does not have a label available for download.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-has-no-downloadable-label"
}
Error - shipment will have a downloadable label that is being generated

The shipment was found, belongs to the user, will have a downloadable label, but it is still being generated. It is expected to be available for download soon, unless an error occurs during the shipping label generation process.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-label-still-generating"
}
Error - shipment failed to generate a shipping label

The shipment was found, belongs to the user, but shipping label generation has failed. The label will never be available for download.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-label-generation-failed"
}
Error - shipment had a downloadable label but is no longer available for download

The shipment was found, belongs to the user, used to have a downloadable label, but has expired. The label will never be available for download.

HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Content-Language: en-US
{
  "error": "shipment-label-unavailable"
}
Success

The shipping label can be retrieved from the URL specified in the Location header and the url field provided in the response body.

Please do not store the provided URL for later use, because it will expire shortly. Rather, issue this API call only when you intend to download the label, and then download the label right away from the provided URL.

HTTP/1.1 302 Found
Content-Type: application/json; charset=utf-8
Content-Language: en-US
Location: https://s3.amazonaws.com/tc-us-prod/shipping_labels/shipping_labels/683286/13268080636554320.gif?AWSAccessKeyId=AKIAJHX5JNRCH5IM74BA&Expires=1396438983&Signature=OjgUPB%2FjW4S9fnfJewNEnw%2B3yzo%3D&response-content-disposition=inline&response-content-type=image%2Fgif
{
  "url": "https://s3.amazonaws.com/tc-us-prod/shipping_labels/shipping_labels/683286/13268080636554320.gif?AWSAccessKeyId=AKIAJHX5JNRCH5IM74BA&Expires=1396438983&Signature=OjgUPB%2FjW4S9fnfJewNEnw%2B3yzo%3D&response-content-disposition=inline&response-content-type=image%2Fgif"
}