User Manual
Help Center/User Manual/Connect Uber Direct: quote, dispatch and track local deliveries

Connect Uber Direct: quote, dispatch and track local deliveries

Last updated 2026-11-01

Copy Client ID and Client Secret from your app at direct.uber.com → Developer → API credentials, copy the separate Customer ID from the Developer page, fill the pickup address as a JSON string in Integration, test the token exchange, and start requesting Uber Direct deliveries.

The Uber Direct connector requests Uber Direct local deliveries from this system: it gets a delivery quote, creates a delivery from that quote, checks delivery status, and can cancel a delivery. It is a last-mile delivery connection only — it does not pull Uber Eats marketplace orders into this system, and it does not sync menus or store catalogs. Quotes and deliveries run under your own Uber Direct customer account and pickup address.

Uber Direct connection steps: app credentials and the separate Customer ID first, pickup address as JSON, then the token test.

Prerequisites#

  • An Uber Direct account, and access to direct.uber.com → Developer, where your app and its API credentials live.
  • You can open your app at direct.uber.com → Developer → your app → API credentials, where the Client ID and Client Secret are shown. The Client Secret is shown only once, so plan to copy it into the connection right away and keep it somewhere safe.
  • You also have the separate Customer ID from direct.uber.com → Developer → Customer ID. It is a different value from the Client ID — the connection uses both, for different things.
  • You know the pickup address of your store or warehouse in its parts — street address, city, state, zip code and country — because the connection takes it as one JSON string, not as separate fields.

Get your credentials#

  1. Go to direct.uber.com → Developer → your app → API credentials.
  2. Copy the Client ID shown on that API credentials page.
  3. Copy the Client Secret shown on the same API credentials page. It is shown only once — copy it now, in full, and keep it somewhere safe. The connection exchanges this pair, Client ID plus Client Secret, for an access token, with the scope eats.deliveries.
  4. Separately, go to direct.uber.com → Developer → Customer ID and copy the Customer ID. Do not confuse it with the Client ID from the app page: the Customer ID names your Uber Direct customer account, and delivery requests are made under it — the API path itself carries it, /v1/customers/{customer_id}/deliveries.
Three IDs, three homes: Client ID and Client Secret live together on your app’s API credentials page, while the Customer ID lives separately on the Developer page. If a delivery request fails right after a passing test, a Customer ID sitting in a Client ID field is the first thing to check.

Fill it into Integration#

  1. Open Integration → Connector Marketplace → Uber Direct → New connection.
  2. client_id — required, Client ID: paste the Client ID from direct.uber.com → Developer → your app → API credentials.
  3. client_secret — required, Client Secret: paste the Client Secret from the same API credentials page, in full. It is a password-type field and is stored as a secret. Remember it was shown only once — work from the copy you saved, not from memory.
  4. customer_id — required, Customer ID: paste the Customer ID from direct.uber.com → Developer → Customer ID. This is not the Client ID — deliveries are requested under this customer account.
  5. pickup_address — required, Pickup address (JSON): fill the pickup address as ONE JSON string, exactly in this shape: {"street_address":["20 W 34th St"],"city":"New York","state":"NY","zip_code":"10001","country":"US"} — with your own store or warehouse values in place of the example values. Note that street_address is an array in square brackets, and all quotes must be straight English quotes. This address is required for placing deliveries; the connection test does not need it.
  6. pickup_name — optional, Pickup name: the name shown for the pickup, for example Merchant or your store name. pickup_phone_number — optional, Pickup phone: a number that reaches the pickup point, for example +15551234567.

Test the connection#

Click Test connection. This test is the token exchange itself: the connection sends your client_id and client_secret to Uber’s sign-in service (grant type client_credentials, scope eats.deliveries) and getting an access token back counts as a pass. Exchanging a token has no side effects — it creates no delivery and changes nothing — which is why it can serve as the test. If the answer comes back without an access token, the test fails with a BAD_JSON result: the exchange did not return what the connection needs, which almost always means the Client ID or Client Secret does not match. The test does not use your pickup_address and does not check that your customer_id can really place deliveries — so a passing test with a wrong address or a wrong Customer ID is possible, and those mistakes only appear later, when you quote or create a delivery. If you run the test before saving any credentials, the result is a simulation check only — save the real credentials and test again for a real result.

Mapping / pick a template#

Uber Direct needs no order mapping — it works on deliveries, not orders. What you confirm here is the delivery flow every request follows: a quote comes first, and a delivery is then created from that quote — creating a delivery always carries the quote it came from, so there is no direct create without a quote. Pickup comes from the pickup_address JSON on the connection, and each request takes its drop-off address, contact and items from the shipment in this system. Before activating, run one real quote and one test delivery to your own address, and check the quoted price, the pickup address as parsed from the JSON, and the drop-off details against the shipment.

Uber Direct delivery flow: token first, then quote, then create from the quote, then track.

Activate#

After activation, shipments in this system can request Uber Direct deliveries: the connection exchanges a token as needed, quotes the delivery under your Customer ID, creates the delivery from the accepted quote, keeps the delivery status on the shipment, and can cancel a delivery that has not been picked up yet. Watch the first real deliveries in Runs / Logs before leaving the connection unattended — especially the first quote, because the test does not check the pickup address or the Customer ID.

What this connection does not do: it does not bring Uber Eats marketplace orders into this system, it does not sync menus or store catalogs, and it does not settle courier pay or Uber billing for you. It only quotes, creates, tracks and cancels Uber Direct deliveries for shipments you send through it.

FAQ#

Test fails and no access token comes back — BAD_JSON

The token exchange did not return an access token, so the connection had nothing to work with and reported BAD_JSON. The usual cause is that the Client ID or the Client Secret does not match: one of them was copied wrong, the secret was trimmed, or a different app’s credentials were used.

Go back to direct.uber.com → Developer → your app → API credentials and re-copy the pair from that same page: Client ID into client_id and Client Secret into client_secret, in full and from the same app. Then test again.

Test passes, but quotes or deliveries fail right away

The test only proves the token exchange with client_id and client_secret. It does not use your pickup_address and does not check your customer_id, so a wrong Customer ID or a broken pickup address passes the test and only fails when a real quote or delivery tries to run under that customer account, from that pickup address.

Check the two values the test does not cover: customer_id against direct.uber.com → Developer → Customer ID, and pickup_address against the JSON shape in the fill-in step, character by character. Fix whichever is wrong, save, and run the quote again.

I filled the Customer ID where the Client ID belongs, or the other way round

The two IDs look alike but do different jobs and come from different pages. The Client ID belongs to your app and is used, with the Client Secret, to exchange a token. The Customer ID names your Uber Direct customer account and rides in the delivery path itself, /v1/customers/{customer_id}/deliveries. Swapped, the token exchange or the delivery request fails even though both fields are filled.

Put each ID back in its own field, from its own page: Client ID from direct.uber.com → Developer → your app → API credentials into client_id, and Customer ID from direct.uber.com → Developer → Customer ID into customer_id. Save and test again.

Deliveries fail because of the pickup address, even though the test passed

This is expected behaviour for a broken address: the connection test never looks at pickup_address, so it cannot catch an address problem. The address is only used when a delivery is actually placed, which is when a malformed JSON string — street_address typed as plain text instead of an array, or curly quotes pasted from a document — stops the request.

Rewrite pickup_address by hand in the exact shape from the fill-in step: {"street_address":["20 W 34th St"],"city":"New York","state":"NY","zip_code":"10001","country":"US"} with your own values — street_address as an array in square brackets, straight English quotes throughout, and no extra text before or after the JSON. Save and place the delivery again.

I lost the Client Secret — it is not shown anymore

That is how the API credentials page works: the Client Secret is shown only once, at the moment it is created. Once you leave that moment, the page no longer shows the value, so a secret you did not save cannot be read back from the page.

Create a new Client Secret for the same app at direct.uber.com → Developer → your app → API credentials, copy it immediately this time, paste it into client_secret on the connection, and keep a copy somewhere safe. Then test again — the connection will exchange a token with the new secret.

Creating a delivery asks for a quote first

That is the normal Uber Direct flow, not an error in your values: a delivery is always created from a quote. The quote fixes the delivery details and price first, and the create step then carries that quote with it — there is no separate direct-create path that skips the quote.

Run the flow in order: request a quote for the shipment first, check the quoted price and details, accept it, and then create the delivery from that quote. If a quote has gone stale, request a fresh quote and create from the new one instead of reusing the old one.