Skip to content

Hassam-01/api-delivery-uber

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Uber Direct API - Delivery Endpoints

This API provides integration with Uber Direct for creating delivery quotes and managing deliveries.

Base URL

http://localhost:5000/api

Security Measures

This API implements several security measures to protect against abuse and ensure secure operation:

Rate Limiting

To prevent abuse and ensure fair usage, all endpoints are rate-limited based on IP address:

  • Health Check: No limit (unlimited)
  • Get Delivery Quote: 10 requests per minute
  • Create Delivery: 5 requests per minute
  • Get Delivery: 20 requests per minute
  • Update Delivery: 10 requests per minute
  • Cancel Delivery: 5 requests per minute
  • List Deliveries: 5 requests per minute
  • Admin List Deliveries: 2 requests per minute
  • Proof of Delivery: 10 requests per minute
  • Find Stores: 10 requests per minute

Rate limits are enforced using Flask-Limiter. Exceeding these limits will result in a 429 (Too Many Requests) response.

Input Validation

  • Phone Numbers: Must start with + followed by digits only (e.g., +1234567890)
  • Coordinates: Latitude must be between -90 and 90, longitude between -180 and 180
  • Required Fields: All mandatory fields are validated; invalid data is rejected with appropriate error messages

Configuration Security

  • Environment Variables: All sensitive configuration (API keys, secrets) must be set via environment variables
  • Validation on Startup: The application validates required environment variables on startup and fails to start if any are missing
  • OAuth Token Management: Access tokens are automatically refreshed when expired, preventing unauthorized API calls

Data Protection

  • No Plaintext Secrets: Secrets are never logged or exposed in responses
  • Secure Token Storage: OAuth tokens are managed securely in memory with automatic expiration handling

Endpoints

1. Get Delivery Quote

POST /deliveries/quote

Get a delivery quote from Uber for a pickup and dropoff location.

Request Body

{
  "pickup_address": {
    "street_address": "string",
    "city": "string",
    "state": "string",
    "zip_code": "string",
    "country": "US"
  },
  "dropoff_address": {
    "street_address": "string" | ["string", "string"],
    "city": "string",
    "state": "string",
    "zip_code": "string",
    "country": "US"
  },
  "external_store_id": "string",
  "pickup_latitude": 37.7749,
  "pickup_longitude": -122.4194,
  "dropoff_latitude": 37.7849,
  "dropoff_longitude": -122.4094,
  "pickup_ready_dt": "2025-10-14T10:00:00Z",
  "pickup_deadline_dt": "2025-10-14T11:00:00Z",
  "dropoff_ready_dt": "2025-10-14T11:00:00Z",
  "dropoff_deadline_dt": "2025-10-14T12:00:00Z",
  "pickup_phone_number": "+15555555555",
  "dropoff_phone_number": "+15555555555",
  "manifest_total_value": 2500,
  "items": [
    {
      "name": "Package description",
      "description": "Additional details",
      "quantity": 1,
      "value": 25.00
    }
  ]
}

Required Fields

  • pickup_address - Pickup location details
  • dropoff_address - Dropoff location details

Optional Fields

  • external_store_id - Store identifier (must match for delivery creation)
  • pickup_latitude/longitude - Precise pickup coordinates
  • dropoff_latitude/longitude - Precise dropoff coordinates
  • pickup_ready_dt/deadline_dt - Pickup time window (RFC 3339 format)
  • dropoff_ready_dt/deadline_dt - Dropoff time window (RFC 3339 format)
  • pickup_phone_number/dropoff_phone_number - Contact numbers (must include country code)
  • manifest_total_value - Total value in cents (e.g., $25.00 = 2500)
  • items - Array of items being delivered

Example Request

curl -X POST "http://localhost:5000/api/deliveries/quote" \
-H "Content-Type: application/json" \
-d '{
  "pickup_address": {
    "street_address": "123 Market St",
    "city": "San Francisco",
    "state": "CA",
    "zip_code": "94103",
    "country": "US"
  },
  "dropoff_address": {
    "street_address": "500 Mission St",
    "city": "San Francisco",
    "state": "CA",
    "zip_code": "94105",
    "country": "US"
  },
  "external_store_id": "store_12345"
}'

Example Response

{
  "success": true,
  "quote": {
    "id": "dqt_7oB_OKLmRVy6LUWyjqfKxg",
    "kind": "delivery_quote",
    "currency_code": "usd",
    "estimated_at": "2025-10-14T10:00:00Z",
    "expires_at": "2025-10-14T11:00:00Z",
    "fee": 640,
    "duration": 1800
  }
}

2. Create Delivery

POST /deliveries

Create a new delivery using a previously obtained quote.

Request Body

{
  "quote_id": "dqt_7oB_OKLmRVy6LUWyjqfKxg",
  "pickup_name": "Store Name",
  "pickup_address": {
    "street_address": "string" | ["string", "string"],
    "city": "string",
    "state": "string",
    "zip_code": "string",
    "country": "US"
  },
  "pickup_phone_number": "string",
  "dropoff_name": "Recipient Name",
  "dropoff_address": {
    "street_address": "string" | ["string", "string"],
    "city": "string",
    "state": "string",
    "zip_code": "string",
    "country": "US"
  },
  "dropoff_phone_number": "string",
  "manifest_items": [
    {
      "name": "Item name",
      "quantity": 1,
      "weight": 30,
      "dimensions": {
        "length": 40,
        "height": 40,
        "depth": 40
      },
      "size": "small",
      "price": 100
    }
  ],
  "external_store_id": "store_12345",
  "pickup_business_name": "Business Name",
  "pickup_latitude": 37.7749,
  "pickup_longitude": -122.4194,
  "pickup_notes": "Special pickup instructions",
  "pickup_verification": {
    "signature_requirement": {
      "enabled": true,
      "collect_signer_name": true,
      "collect_signer_relationship": true
    },
    "picture": true
  },
  "dropoff_business_name": "Business Name",
  "dropoff_latitude": 37.7849,
  "dropoff_longitude": -122.4094,
  "dropoff_notes": "Special delivery instructions",
  "dropoff_seller_notes": "Fragile - handle with care",
  "dropoff_verification": {
    "signature_requirement": {
      "enabled": true,
      "collect_signer_name": true,
      "collect_signer_relationship": true
    },
    "barcodes": [
      {
        "value": "123456789",
        "type": "CODE39"
      }
    ]
  },
  "deliverable_action": "deliverable_action_meet_at_door",
  "manifest_reference": "REF0000001",
  "manifest_total_value": 1000,
  "idempotency_key": "unique-key-123",
  "return_verification": {
    "picture": true
  },
  "external_id": "external-order-123",
  "user_fees_summary": [
    {
      "fee_type": "promo",
      "amount": -300,
      "user_fee_tax_info": [
        {
          "tax_rate": 200
        }
      ]
    }
  ]
}

Required Fields

  • quote_id - Quote ID from previous quote request
  • pickup_name - Pickup contact name
  • pickup_address - Pickup location details
  • pickup_phone_number - Pickup contact phone
  • dropoff_name - Dropoff contact name
  • dropoff_address - Dropoff location details
  • dropoff_phone_number - Dropoff contact phone
  • manifest_items - Array of items to deliver

Optional Fields

  • external_store_id - Must match the quote's external_store_id
  • pickup_business_name/dropoff_business_name - Business names
  • pickup_latitude/longitude - Precise coordinates
  • pickup_notes/dropoff_notes - Special instructions
  • pickup_verification/dropoff_verification - Verification requirements
  • deliverable_action - Delivery method (e.g., "deliverable_action_meet_at_door")
  • manifest_reference - Reference number
  • manifest_total_value - Total value in cents
  • idempotency_key - Prevents duplicate deliveries
  • return_verification - Return verification settings
  • external_id - External order identifier
  • user_fees_summary - Fee and tax information

Example Request

curl -X POST "http://localhost:5000/api/deliveries" \
-H "Content-Type: application/json" \
-d '{
  "quote_id": "dqt_7oB_OKLmRVy6LUWyjqfKxg",
  "pickup_name": "My Store",
  "pickup_address": {
    "street_address": "123 Market St",
    "city": "San Francisco",
    "state": "CA",
    "zip_code": "94103",
    "country": "US"
  },
  "pickup_phone_number": "4444444444",
  "dropoff_name": "Reese Ippient",
  "dropoff_address": {
    "street_address": ["285 Fulton St", ""],
    "state": "NY",
    "city": "New York",
    "zip_code": "10006",
    "country": "US"
  },
  "dropoff_phone_number": "5555555555",
  "manifest_items": [
    {
      "name": "Cell phone box",
      "quantity": 1,
      "weight": 30,
      "dimensions": {
        "length": 40,
        "height": 40,
        "depth": 40
      }
    }
  ],
  "external_store_id": "store_12345"
}'

Example Response

{
  "success": true,
  "delivery": {
    "id": "del_7oB_OKLmRVy6LUWyjqfKxg",
    "status": "pending",
    "quote_id": "dqt_7oB_OKLmRVy6LUWyjqfKxg",
    "fee": 640,
    "currency": "usd",
    "created": "2025-10-14T10:08:00.48Z",
    "tracking_url": "https://delivery.uber.com/orders/...",
    "pickup": {
      "name": "My Store",
      "address": "123 Market St, San Francisco, CA 94103, US",
      "phone_number": "4444444444"
    },
    "dropoff": {
      "name": "Reese Ippient",
      "address": "285 Fulton St, New York, NY 10006, US",
      "phone_number": "5555555555"
    },
    "manifest_items": [
      {
        "name": "Cell phone box",
        "quantity": 1,
        "weight": 30,
        "dimensions": {
          "length": 40,
          "height": 40,
          "depth": 40
        }
      }
    ]
  }
}

3. Get Delivery

GET /deliveries/<delivery_id>

Retrieve the details of a specific delivery by its delivery ID. The customer ID is automatically included from the environment configuration.

Path Parameters

  • delivery_id (string, required) - Unique identifier for the delivery (starts with del_)

Example Request

curl -X GET "http://localhost:5000/api/deliveries/del_aEOkr3JwTcKEaupQaj3W-g" \
-H "Content-Type: application/json"

Example Response

{
  "id": "del_aEOkr3JwTcKEaupQaj3W-g",
  "quote_id": "dqt_7oB_OKLmRVy6LUWyjqfKxg",
  "complete": false,
  "courier": {
    "name": "John Doe",
    "phone_number": "+15555555555",
    "location": {
      "lat": 37.7749,
      "lng": -122.4194
    },
    "vehicle": {
      "make": "Toyota",
      "model": "Camry",
      "color": "Blue",
      "license_plate": "ABC123"
    }
  },
  "courier_imminent": false,
  "created": "2025-10-14T10:00:00Z",
  "currency": "usd",
  "deliverable_action": "deliverable_action_deliver",
  "dropoff": {
    "name": "Recipient Name",
    "phone_number": "+15555555555",
    "address": {
      "street_address": ["500 Mission St"],
      "city": "San Francisco",
      "state": "CA",
      "zip_code": "94105",
      "country": "US"
    },
    "location": {
      "lat": 37.7849,
      "lng": -122.4094
    },
    "notes": "Second floor, black door to the right"
  },
  "dropoff_deadline": "2025-10-14T12:00:00Z",
  "dropoff_eta": "2025-10-14T11:30:00Z",
  "dropoff_identifier": "",
  "dropoff_ready": "2025-10-14T11:00:00Z",
  "external_id": "EI000001",
  "fee": 640,
  "kind": "delivery",
  "live_mode": true,
  "manifest": {
    "reference": "REF0000001",
    "total_value": 2500
  },
  "manifest_items": [
    {
      "name": "Package",
      "quantity": 1,
      "size": "small",
      "dimensions": {
        "length": 40,
        "height": 40,
        "depth": 40
      },
      "weight": 30,
      "price": 100
    }
  ],
  "pickup": {
    "name": "Store Name",
    "phone_number": "+15555555555",
    "address": {
      "street_address": ["123 Market St"],
      "city": "San Francisco",
      "state": "CA",
      "zip_code": "94103",
      "country": "US"
    },
    "location": {
      "lat": 37.7749,
      "lng": -122.4194
    },
    "notes": "Follow big green 'Pickup' signs in the parking lot"
  },
  "pickup_deadline": "2025-10-14T11:00:00Z",
  "pickup_eta": "2025-10-14T10:15:00Z",
  "pickup_ready": "2025-10-14T10:00:00Z",
  "status": "pickup",
  "tip": 200,
  "tracking_url": "https://delivery.uber.com/orders/12345678-1234-1234-1234-123456789012",
  "undeliverable_action": "",
  "undeliverable_reason": "",
  "updated": "2025-10-14T10:15:00Z",
  "uuid": "12345678123412341234123456789012"
}

Error Responses

  • 400 Bad Request - Invalid delivery ID format or API error
  • 404 Not Found - Delivery not found

4. Get Customer Deliveries (Admin)

GET /admin/deliveries

Retrieve a list of deliveries for the configured customer with optional filtering. This endpoint uses the customer ID from the environment configuration.

Query Parameters

  • filter (string, optional) - Filter deliveries by delivery state. Valid values: "pending", "pickup", "pickup_complete", "dropoff", "delivered", "canceled", "returned", "ongoing"
  • external_store_id (string, optional) - Filter deliveries by external_store_id
  • start_dt (string, optional) - Beginning of the filter time range (RFC 3339 format). Defaults to 3 months prior to current time if not provided
  • end_dt (string, optional) - End of the filter time range (RFC 3339 format). Defaults to current time if not provided
  • limit (integer, optional) - Maximum number of responses to return
  • offset (integer, optional) - Offset of response objects for pagination

Example Request

curl -X GET "http://localhost:5000/api/admin/deliveries?filter=delivered&limit=10" \
-H "Content-Type: application/json"

Example Response

{
  "success": true,
  "deliveries": [
    {
      "id": "del_7oB_OKLmRVy6LUWyjqfKxg",
      "status": "delivered",
      "quote_id": "dqt_7oB_OKLmRVy6LUWyjqfKxg",
      "fee": 640,
      "currency": "usd",
      "created": "2025-10-14T10:08:00.48Z",
      "tracking_url": "https://delivery.uber.com/orders/...",
      "pickup": {
        "name": "My Store",
        "address": "123 Market St, San Francisco, CA 94103, US",
        "phone_number": "4444444444"
      },
      "dropoff": {
        "name": "Reese Ippient",
        "address": "285 Fulton St, New York, NY 10006, US",
        "phone_number": "5555555555"
      },
      "manifest_items": [
        {
          "name": "Cell phone box",
          "quantity": 1,
          "weight": 30,
          "dimensions": {
            "length": 40,
            "height": 40,
            "depth": 40
          }
        }
      ]
    }
  ]
}

Important Notes

  1. External Store ID: If provided in the quote request, it must match exactly in the delivery creation request.

  2. Address Format: Street addresses can be either a string or an array of strings for multi-line addresses.

  3. Phone Numbers: Must include country code (e.g., +1 for US numbers).

  4. Coordinates: If provided, they must be geographically close to the address. Uber validates coordinate/address matching.

  5. Quote Expiration: Quotes expire after a certain time (typically 1 hour). Use fresh quotes for delivery creation.

  6. Idempotency: Use idempotency_key to prevent duplicate deliveries when retrying failed requests.

  7. Verification: Signature and picture verification can be enabled for additional security.

Additional Endpoints

5. Health Check

GET /health

Check if the API service is running and healthy.

Example Request

curl -X GET "http://localhost:5000/api/health" \
-H "Content-Type: application/json"

Example Response

{
  "status": "ok"
}

6. Update Delivery

POST /deliveries/<delivery_id>

Update details of an existing delivery. Note: Updates are only allowed within certain time windows before pickup.

Path Parameters

  • delivery_id (string, required) - Unique identifier for the delivery (starts with del_)

Request Body

{
  "dropoff_notes": "Updated delivery instructions",
  "dropoff_seller_notes": "Handle with extra care",
  "manifest_reference": "REF0000002",
  "pickup_notes": "Updated pickup instructions",
  "dropoff_verification": {
    "barcodes": [
      {
        "value": "W1129082649-1",
        "type": "CODE39"
      }
    ]
  },
  "tip_by_customer": 500
}

Optional Fields

  • dropoff_notes - Updated delivery instructions
  • dropoff_seller_notes - Seller notes for courier
  • manifest_reference - Updated reference number
  • pickup_notes - Updated pickup instructions
  • dropoff_verification - Updated verification requirements
  • tip_by_customer - Additional tip amount in cents

Example Request

curl -X POST "http://localhost:5000/api/deliveries/del_aEOkr3JwTcKEaupQaj3W-g" \
-H "Content-Type: application/json" \
-d '{
  "dropoff_notes": "Ring doorbell twice",
  "tip_by_customer": 300
}'

Example Response

{
  "success": true,
  "delivery": {
    "id": "del_aEOkr3JwTcKEaupQaj3W-g",
    "status": "pending",
    "updated": "2025-10-14T10:30:00Z"
  }
}

7. Cancel Delivery

POST /deliveries/<delivery_id>/cancel

Cancel an ongoing or scheduled delivery.

Path Parameters

  • delivery_id (string, required) - Unique identifier for the delivery (starts with del_)

Example Request

curl -X POST "http://localhost:5000/api/deliveries/del_aEOkr3JwTcKEaupQaj3W-g/cancel" \
-H "Content-Type: application/json"

Example Response

{
  "id": "del_aEOkr3JwTcKEaupQaj3W-g",
  "status": "canceled",
  "canceled_at": "2025-10-14T10:30:00Z"
}

8. List Deliveries

GET /deliveries

Retrieve a list of deliveries stored in the local database with optional filtering.

Query Parameters

  • status (string, optional) - Filter deliveries by status
  • limit (integer, optional) - Maximum number of deliveries to return (default: 50, max: 100)
  • offset (integer, optional) - Number of deliveries to skip for pagination (default: 0)

Example Request

curl -X GET "http://localhost:5000/api/deliveries?status=delivered&limit=10&offset=0" \
-H "Content-Type: application/json"

Example Response

{
  "success": true,
  "deliveries": [
    {
      "_id": "670d1234567890abcdef12345",
      "delivery_id": "del_aEOkr3JwTcKEaupQaj3W-g",
      "status": "delivered",
      "created_at": "2025-10-14T10:00:00Z",
      "updated_at": "2025-10-14T11:30:00Z"
    }
  ],
  "count": 1
}

Note: The count field represents the number of deliveries returned in this response, not the total number of deliveries matching the filters.


9. Proof of Delivery

POST /deliveries/<delivery_id>/proof-of-delivery

Retrieve proof of delivery information including signature images or verification details.

Path Parameters

  • delivery_id (string, required) - Unique identifier for the delivery (starts with del_)

Request Body

{
  "waypoint": "dropoff",
  "type": "signature"
}

Required Fields

  • waypoint - Either "pickup" or "dropoff"
  • type - Type of proof: "signature", "picture", or "pincode"

Example Request

curl -X POST "http://localhost:5000/api/deliveries/del_aEOkr3JwTcKEaupQaj3W-g/proof-of-delivery" \
-H "Content-Type: application/json" \
-d '{
  "waypoint": "dropoff",
  "type": "signature"
}'

Example Response

{
  "id": "pod_1234567890",
  "waypoint": "dropoff",
  "type": "signature",
  "data": "iVBORw0KGgoAAAANSUhEUgAA...",
  "captured_at": "2025-10-14T11:30:00Z"
}

10. Find Stores

GET /direct/stores

Find stores that can deliver to a specific location based on latitude and longitude coordinates.

Query Parameters

  • latitude (number, required) - Latitude of the dropoff location
  • longitude (number, required) - Longitude of the dropoff location

Example Request

curl -X GET "http://localhost:5000/direct/stores?latitude=40.7128&longitude=-74.0060" \
-H "Content-Type: application/json"

Example Response

{
  "stores": [
    {
      "external_id": "store_123",
      "name": "Example Store",
      "address": {
        "street1": "123 Main St",
        "street2": "Suite 100",
        "city": "New York",
        "state": "NY",
        "zipcode": "10001",
        "country_iso2": "US"
      }
    }
  ]
}

Error Responses

Both endpoints return errors in the following format:

{
  "success": false,
  "error": {
    "code": "error_code",
    "message": "Error description",
    "metadata": {
      "param_details": "Additional error details"
    }
  }
}

Common error codes:

  • invalid_params - Invalid request parameters
  • address_undeliverable - Address cannot be delivered to
  • expired_quote - Quote has expired
  • missing_payment - Payment method required

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages