One moment while we take you to your dashboard...

Postmates API

Using the Postmates Delivery API, developers can integrate our on-demand local delivery platform into their applications. The API is designed to allow application developers to check prices, schedules, book a delivery, then follow updates on that delivery till completion.


To get started using the Postmates Delivery API:

What can the API do?

You can use the Postmates API to utilize our fleet of couriers to deliver your products within our geographic zones.

Here is the flow of events that developers most commonly follow when using our API:

  • To see if a delivery is possible, request a delivery quote. This endpoint takes in two addresses and returns a fee, ETA, and other information about a potential delivery.
  • After you have evaluated whether the quoted price and delivery estimate meets your needs, you can create a delivery.
  • While a delivery is in progress, you can track its status in real-time in the developer dashboard, by polling the API, or with webhooks.

What can be delivered using the API?

You can use the Postmates API to deliver most items that can be carried by an average person, including alcohol. Please see our Shipping Policy & Terms of Service for more information on what can and can not be delivered on our platform.


The Postmates API requires authentication by HTTP Basic Auth headers. Your API key should be included as the username. The password should be left empty.

The actual header that is used will be a base64-encoded string like this:


Most of the endpoints provided in the Postmates API are in relation to a specific customer. You'll need to provide your customer id and include it in the URL.

Security Note: Treat your API key as a password and never make it available outside of your direct control. The API key by design enables direct access to the Postmates API on your behalf and so it is inappropriate and unsafe to share the API key among multiple parties.


The base URL for all requests to the Postmates API is:

Our API is REST-based. This means:

  • It make use of standard HTTP verbs like GET, POST, DELETE.
  • The API uses standard HTTP error responses to describe errors.
  • Authentication is specified with HTTP Basic Authentication.

All requests use standard query encoding.

POST data should be encoded as standard application/x-www-form-urlencoded.

Rate Limiting

There is a global rate limit for API requests.

Environment Requests/minute
Sandbox 7500
Production 10000

Exceeding this rate limit will result in a 429 response.


Versioning allows us to provide developers a consistent experience. We provide two levels of versioning:

  • Resource: All endpoints are prefixed with a version such as /v1. This version refers to the overall layout of the endpoints and response standards.
  • Client: Developers can ensure consistent fields and formats by specifying a version as a HTTP header.
    • X-Postmates-Version header such as X-Postmates-Version: 20140825


Please format pickup and dropoff addresses this way:

Street Address, City, State, Zip

Any other information, like apartment number, door codes, "care of" instructions, should all be added to pickup or dropoff notes fields. Any extra information included may result in a malformed address, and our geocoder will not be able to find the location.


The Postmates API uses HTTP status codes to indicate the status of your requests. This includes successful and unsuccessful responses.

All responses are in JSON.

Status Codes

  • 200 - OK: Everything went as planned.
  • 304 - Not Modified: Resource hasn't been updated since the date provided. See Caching below.
  • 400 - Bad Request: You did something wrong. Often a missing argument or parameter.
  • 401 - Unauthorized: Authentication was incorrect.
  • 404 - Not Found
  • 429 - Too Many Requests
  • 500 - Internal Server Error: We had a problem processing the request.
  • 503 - Service Unavailable: Try again later.


Error responses include details about what went wrong.

  "kind": "error",
  "code": "invalid_params",
  "message": "The parameters of your request were invalid.",
  "params": {
    "dropoff_name": "Dropoff name is required.",
    "dropoff_phone_number": "Dropoff phone number must be valid phone number."

Error Codes

This list will likely become more comprehensive as features are implemented.

  • invalid_params - The indicated parameters were missing or invalid.
  • unknown_location - We weren't able to understand the provided address. This usually indicates the address is wrong, or perhaps not exact enough.
  • rate_limit_exceeded - This API key has made too many requests.
  • customer_not_approved - You account has not been approved to create deliveries. Please refer to our approval guidelines for more information.
  • account_suspended
  • not_found
  • service_unavailable
  • delivery_limit_exceeded - You have hit the maximum amount of ongoing deliveries allowed.
  • customer_limited - Your account's limits have been exceeded.
  • couriers_busy - All of our couriers are currently busy.


Responses often indicate a type of object being described. Though this can often be inferred from the resource being requested, but we like to be explicit:

  kind: "user",
  name: "Alice"

Some responses might include a list of objects:

  kind: "list",
  data: [
      kind: "user",
      name: "Alice"
      kind: "user",
      name: "Bob"


When a response involves a currency, it is described as follows:

  amount: 799,
  currency: "usd"

This indicates a value of $7.99 in USD.


Times are formatted according to ISO8601 and reported only in UTC time. For example:

  created: "2014-08-26T10:04:03Z",

Objects will often have attributes like "created" and "updated".

Large Result Sets

Some resources may have too many objects to include in a single response. To support pagination, we include attributes such as:

  total_count: 100,
  next_href: "",
  data: [...]

By requesting the next_href, the client will receive the next set of objects.

Clients can also request a specific number of response objects by using the limit query parameter.


Some objects have a geographic location associated with them. This typically of the form:

  "location" : {
    "lat" : 37.42291810,
    "lng" : -122.08542120


Webhooks allow you to receive real-time updates to your ongoing deliveries. By configuring a URL we can POST updates to, you'll get the most up-to-date information to show to your customers.

Webhook Endpoint

To use webhooks, you'll need to configure your own web application to accept HTTP POST requests from us. These requests will contain JSON objects representing the event that has occurred.

Configure this URL endpoint in the developer dashboard. You can choose live or test mode.

The Event Object

Event objects follow a standard format. Each event has:

  • A kind to indicate what type of event has been provided.
  • A unique id for this event instance.
  • A flag indicating if the event applies to live_mode data.
  • Timestamp indicating when the event was generated.
  • One or more fields specific to each sub-type.
  • The id of the object the event applies to (example: delivery_id).
  • An updated version of the object the event applies to. For example, all delivery events will include a full delivery object as the data field.
  "kind": "event.delivery_status",
  "id": "evt_KC9LLdlTwr7udF",
  "delivery_id": "del_3vDjjkd21b",
  "status": "pickup",
  "data": {
    "kind": "delivery",
    "id": "del_3vDjjkd21b",
    "status": "pickup",
  "created": "2014-08-26T10:04:03Z",
  "live_mode": false

Supported Event Types

  • delivery_status - Sent each time the status field on a delivery changes.
    • Event will contain the field status and include an updated delivery object as the data.
  • courier_update - Sent every 30 seconds as a courier changes locations.
    • Event will contain the field location with lat and lng fields. An updated delivery object will be included as the data.
  • delivery_return - Sent when a delivery has been returned to pickup location
    • Event will contain the field status and include an updated delivery object as the data.


Webhook versioning is based on when you configure the webhook. The version string will be provided along with the webhook request in a X-Postmates-Version HTTP header.


Webhooks created through the Postmates API can be verified by calculating a digital signature.

Each webhook request has a X-Postmates-Signature header which is generated using a shared secret and the payload of the webhook request.

To verify that the request came from Postmates, pass the secret and payload through the SHA-256 hashing algorithm, and make sure it's equal to X-Postmates-Signature.

Here's an example in Python:

>>> import hashlib, hmac
>>> api_secret = 'c5c26d5a-70d6-46c7-a652-d7c09825ad29'
>>> payload = '{"kind": "event.courier_update", "location": {"lat": 37.7974109, "lng": -122.424145}}' # Shortened for this example
>>>, payload, hashlib.sha256).hexdigest()


You can monitor webhooks in the Postmates Partner Dashboard. Webhook event logs are saved for 30 days.

Test Mode

For your development convenience, we provide a test mode for our API. Using a test API key will allow you to exercise all the endpoints. We even have a special robot courier named Robo that will deliver your imaginary goods. This courier updates every 10 seconds.

All responses during live mode will have an extra attribute:

  "live_mode": true,

If you want to play around with our endpoints, you can use Postman:


The Create a Delivery API endpoint has optional post parameters for specifying when various delivery events occur.

  • robo_pickup - When Robo will start moving towards the pickup.
  • robo_pickup_complete - When Robo will have picked up the items.
  • robo_dropoff - When Robo will start moving towards the dropoff.
  • robo_delivered - When Robo will complete the delivery.


The interface is a key value pair where the event type has a corresponding time which is relative to the creation date of the job. If an event is set to 00:10:00, then Robo will start the event in 10 minutes.

  • hh - hours
  • mm - minutes
  • ss - seconds

Undeliverable Deliveries

The Create a Delivery API endpoint has optional post parameters that can be used to simulate an undeliverable delivery.

  • robo_undeliverable_reason - Optional parameter to specify the reason for an undeliverable delivery. Either 'customer_not_available' or 'customer_id_check_failed'.
  • robo_undeliverable_action - Optional parameter to specify the action for the robo courier to take for an undeliverable delivery. Either 'returned', 'discarded' or 'left_at_door'.

Post Example

Here is an example where Robo will start pickup in 10 minutes, pickup_complete in 20 minutes, dropoff in 21 minutes and delivered in 34 minutes.

      POST /v1/customers/:customer_id/deliveries

      manifest="a box of kittens"
      manifest_reference="Optional reference that identifies the box of kittens"
      pickup_name="The Warehouse"
      pickup_address="20 McAllister St, San Francisco, CA"
      pickup_business_name="Optional Pickup Business Name, Inc."
      pickup_notes="Optional note that this is Invoice #123"
      dropoff_address="101 Market St, San Francisco, CA"
      dropoff_business_name="Optional Dropoff Business Name, Inc."
      dropoff_notes="Optional note to ring the bell"


Pathing on Robo is as the crow flies between its location and either its pickup or dropoff point depending on the job state. The rate in which Robo moves is based on the when the next event occurs. For example, if pickup is at 00:00:00 and pickup_complete is at 00:10:00 then the rate is the distance between Robo's current location divided by 10 minutes.

Invalid Event Configurations

Delivery states happen in order so if the event configuration does not respect this order then the event configuration is ignored.

How do I get a production key?

When you're ready to start doing live deliveries, update your payment details and use your production API key.