RentADriver
Obtener clave API
Esta página solo está disponible en inglés por ahora.La referencia de la API, los textos legales y las guías extensas se mantienen en inglés.
REST API v1

RentADriver API

Base URL https://api.rentadriver.ai/v1. JSON in, JSON out. Money is in integer minor units (cents). Timestamps are ISO-8601 UTC. Every response has success, and delivery responses carry next_action.

Quick start

# 1. Price it — no auth
curl -X POST https://api.rentadriver.ai/v1/quotes -H 'Content-Type: application/json' -d '{
  "pickup":   {"address": "Queen Victoria Market, Melbourne", "contact_name": "Stall 12"},
  "dropoffs": [{"address": "Flinders Street Station, Melbourne", "contact_name": "Alex", "contact_phone": "+61400000000"}],
  "items":    [{"description": "Box of pastries", "size_class": "M", "category": "food"}],
  "urgency":  "asap"
}'

# 2. Get a key (once) — or use the Console
curl -X POST https://api.rentadriver.ai/v1/signup -H 'Content-Type: application/json' -d '{"name":"My Agent","email":"me@example.com"}'

# 3. Book it — funds held, dispatch starts
curl -X POST https://api.rentadriver.ai/v1/deliveries -H 'x-api-key: rd_live_…' -H 'Content-Type: application/json' \
  -d '{"quote_id": "<quote.id>", "instructions": "Ring twice", "idempotency_key": "order-1042"}'

# 4. Follow it
curl https://api.rentadriver.ai/v1/deliveries/<id>/track -H 'x-api-key: rd_live_…'
curl -N https://api.rentadriver.ai/v1/deliveries/<id>/events?stream=1 -H 'x-api-key: rd_live_…'   # SSE

# 5. Proof, then confirm (auto after 24h)
curl https://api.rentadriver.ai/v1/deliveries/<id>/proof -H 'x-api-key: rd_live_…'
curl -X POST https://api.rentadriver.ai/v1/deliveries/<id>/confirm -H 'x-api-key: rd_live_…'

Authentication

Send your key as x-api-key: rd_live_… (or Authorization: Bearer rd_live_…). Keys are created from the Console, the POST /v1/signup endpoint, or the MCP signup tool. Up to 10 active keys per account; revoke from DELETE /v1/api-keys/:id. Quotes, coverage, service areas, stats and recipient tracking need no key.

Statuses

StatusMeaningMoney
quotedCreated, not funded
fundedScheduled; dispatch starts 45 min before the windowheld
dispatchingOffering to on-shift drivers in expanding radius wavesheld
assignedA driver acceptedheld
en_route_pickup → at_pickup → picked_upDriver steps with pickup photoheld
en_route_dropoff → at_dropoff → deliveredDrop-off proof capturedheld
confirmed / paidYou confirmed (or 24h passed); driver is paidcaptured
no_driver_foundSix waves, no acceptancereleased
cancelledYou cancelled. Free before assignment; 30% of driver pay afterreleased (minus fee)
failedDriver could not complete; a review is openedheld until resolved
disputedYou opened a disputeheld until resolved
returnedItem brought back to pickupcaptured

Pricing model

Each city has a pricing profile. price = max(min_price, base + per_km·km + per_min·(drive + wait)) × size × urgency × vehicle × surge. Driver pay is the higher of the hourly floor (plus mileage) and a share of the price, and the price is lifted if needed so the platform margin never drops below the city minimum. The quote’s breakdown shows every factor, including supply_nearby and surge. Quotes expire after 15 minutes.

Intercity (city to city)

Set service to auto (default) or intercity on POST /v1/quotes or POST /v1/deliveries. When the pickup is in one launch city and the last drop-off is inside, or within 80 km of, another launch city in the same country, the quote comes back with service_kind: "intercity" and an intercity object: lane, speed, departure_at, arrival_by, transit time with rest breaks, and the driver milestone schedule. Up to 3 drop-offs.

  • speed: express (dedicated driver leaves within 2 h, +25 %), standard (dedicated, within 24 h), shared (consolidated lane run at fixed departures, −38 %, no deadhead).
  • Price = origin city base × 4 + tiered km (62 % / 48 % / 40 % of the local per-km rate for ≤100 / ≤300 / >300 km) + deadhead allowance (10 % of the distance to a launch city, 25 % elsewhere) + tolls + insurance (1.5 % of declared value_cents above 50 000), × size × vehicle, then the speed tier. Every component is in breakdown.intercity.
  • Money: the full price is held at booking. 40 % of the driver pay is released at picked_up (event advance_released), the rest on confirm. Cancellation after assignment costs 20 % of the price; none after pickup.
  • GET /v1/intercity/lanes lists lanes both ways with sample prices per speed and the next shared departures. MCP: list_intercity_lanes, get_intercity_quote.

Proof of delivery

Each stop declares proof_required: any of photo, signature, recipient_name, otp, id_check. Defaults: photo at pickup; photo + recipient name at drop-off. The driver app cannot complete a stop without the required proof. GET /v1/deliveries/:id/proof returns signed URLs valid for one hour. For OTP handoff, put the code in metadata.otp and tell the recipient.

Webhooks

Register with POST /v1/webhooks or pass webhook_url per delivery. Each POST carries X-RentADriver-Event and X-RentADriver-Signature: t=<unix>,v1=<hex> where v1 = HMAC-SHA256(secret, t + "." + rawBody). Retries: 1m, 5m, 30m, 2h, 12h. Events: delivery.created|funded|dispatching|assigned|en_route_pickup|at_pickup|picked_up|en_route_dropoff|at_dropoff|delivered|confirmed|paid|no_driver_found|cancelled|failed|disputed|message|location. Prefer SSE (?stream=1) when your agent is long-running.

Shopify

Merchants install the RentADriver app for Shopify from Shopify admin (or from /shopify). It registers a carrier service that answers checkout with a live Same-day by RentADriver rate for addresses inside the shop’s radius, books the delivery on orders/paid (created_via: "shopify", external_ref = order name, metadata.shopify carries the order id), fulfils the order with the tracking link at pickup and posts fulfillment events until delivered. Agents on the same account can list and book Shopify orders: GET /v1/shopify/orders, POST /v1/shopify/orders/:ref/book (order name like #1042; orders the app never saw are fetched from Shopify). MCP: list_shopify_orders, book_shopify_order.

Errors

HTTPcodeWhat to do
400validation_error / bad_requestFix the payload; details lists the paths
401unauthorized / invalid_api_keySend a valid x-api-key
402insufficient_fundsDeposit (card checkout URL or x402), then POST /fund
403spending_capRaise the cap in account controls
409invalid_state / conflict / already_takenRead status and next_action; do not retry blindly
410quote_expired / offer_expiredRequest a new quote
422outside_coverage / prohibited_item / proof_requiredChange the request; see details
429rate_limitedBack off; headers include X-RateLimit-Remaining

Prohibited items

Alcohol, tobacco and vapes, cannabis, weapons and ammunition, explosives and fireworks, controlled or prescription-only medicines without a licensed sender, hazardous or flammable goods, loose lithium batteries, live animals, human remains, cash above the city cap, and anything illegal to transport. Creation is refused with 422 prohibited_item. Food is allowed as a food category without a temperature guarantee.

MCP

npx -y rentadriver-mcp exposes every endpoint below as a tool, plus create_store_pickup, resources (delivery://, coverage://, openapi://spec) and the plan_delivery prompt. Remote transport: https://mcp.rentadriver.ai/mcp with x-api-key. Full MCP tools reference with a description, inputs, returns and auth for each tool.

Reference

Discovery

GET/v1/intercity/lanesIntercity lanes between launch cities with sample prices per speed tier and next shared departures

Responses: 200 OK

GET/v1/service-areasList launch cities

Responses: 200 OK

GET/v1/coverageIs an address/point covered?

Params: addresslatlng

Responses: 200 OK

GET/v1/statsLive platform stats

Responses: 200 OK

Quotes

POST/v1/quotesPrice a delivery (no auth needed)
{
 "type": "object",
 "required": [
  "pickup",
  "dropoffs"
 ],
 "properties": {
  "pickup": {
   "type": "object",
   "required": [],
   "properties": {
    "address": {
     "type": "string",
     "description": "Street address; geocoded server-side if lat/lng omitted"
    },
    "lat": {
     "type": "number"
    },
    "lng": {
     "type": "number"
    },
    "contact_name": {
     "type": "string"
    },
    "contact_phone": {
     "type": "string"
    },
    "instructions": {
     "type": "string"
    },
    "window_start": {
     "type": "string",
     "format": "date-time"
    },
    "window_end": {
     "type": "string",
     "format": "date-time"
    },
    "proof_required": {
     "type": "array",
     "items": {
      "type": "string",
      "enum": [
       "photo",
       "signature",
       "recipient_name",
       "otp",
       "id_check"
      ]
     }
    }
   }
  },
  "dropoffs": {
   "type": "array",
   "minItems": 1,
   "maxItems": 8,
   "items": {
    "type": "object",
    "required": [],
    "properties": {
     "address": {
      "type": "string",
      "description": "Street address; geocoded server-side if lat/lng omitted"
     },
     "lat": {
      "type": "number"
     },
     "lng": {
      "type": "number"
     },
     "contact_name": {
      "type": "string"
     },
     "contact_phone": {
      "type": "string"
     },
     "instructions": {
      "type": "string"
     },
     "window_start": {
      "type": "string",
      "format": "date-time"
     },
     "window_end": {
      "type": "string",
      "format": "date-time"
     },
     "proof_required": {
      "type": "array",
      "items": {
       "type": "string",
       "enum": [
        "photo",
        "signature",
        "recipient_name",
        "otp",
        "id_check"
       ]
      }
     }
    }
   }
  },
  "service": {
   "type": "string",
   "enum": [
    "auto",
    "local",
    "intercity"
   ],
   "default": "auto",
   "description": "auto picks intercity when the drop-off is in another launch city"
  },
  "speed": {
   "type": "string",
   "enum": [
    "express",
    "standard",
    "shared"
   ],
   "default": "standard",
   "description": "Intercity only: express = dedicated driver leaves within 2h; standard = dedicated within 24h; shared = consolidated lane run at fixed departures (cheapest)"
  },
  "items": {
   "type": "array",
   "items": {
    "type": "object",
    "required": [
     "description"
    ],
    "properties": {
     "descriptio

Responses: 200 OK422 outside_coverage / prohibited_item

Account

GET/v1/signup/verifyVerify email from the link sent at signup; unlocks the welcome credit

Params: token

Responses: 200 OK

POST/v1/signupCreate an account + API key (shown once); email verification unlocks the $20 credit
{
 "type": "object",
 "required": [
  "name",
  "email"
 ],
 "properties": {
  "name": {
   "type": "string"
  },
  "email": {
   "type": "string",
   "format": "email"
  },
  "kind": {
   "type": "string",
   "enum": [
    "agent",
    "app",
    "business"
   ]
  },
  "agent_framework": {
   "type": "string"
  }
 }
}

Responses: 201 OK

GET/v1/accountAccount, balance, capabilities🔑 key

Responses: 200 OK

PATCH/v1/account/controlsSpending caps🔑 key
{
 "type": "object",
 "properties": {
  "spending_cap_per_delivery_cents": {
   "type": "integer",
   "nullable": true
  },
  "daily_cap_cents": {
   "type": "integer",
   "nullable": true
  }
 }
}

Responses: 200 OK

GET/v1/api-keysList keys🔑 key

Responses: 200 OK

POST/v1/api-keysCreate key (max 10)🔑 key

Responses: 201 OK

DELETE/v1/api-keys/{id}Revoke key🔑 key

Params: id

Responses: 200 OK

Deliveries

POST/v1/deliveriesCreate (and fund) a delivery🔑 key
{
 "allOf": [
  {
   "type": "object",
   "required": [
    "pickup",
    "dropoffs"
   ],
   "properties": {
    "pickup": {
     "type": "object",
     "required": [],
     "properties": {
      "address": {
       "type": "string",
       "description": "Street address; geocoded server-side if lat/lng omitted"
      },
      "lat": {
       "type": "number"
      },
      "lng": {
       "type": "number"
      },
      "contact_name": {
       "type": "string"
      },
      "contact_phone": {
       "type": "string"
      },
      "instructions": {
       "type": "string"
      },
      "window_start": {
       "type": "string",
       "format": "date-time"
      },
      "window_end": {
       "type": "string",
       "format": "date-time"
      },
      "proof_required": {
       "type": "array",
       "items": {
        "type": "string",
        "enum": [
         "photo",
         "signature",
         "recipient_name",
         "otp",
         "id_check"
        ]
       }
      }
     }
    },
    "dropoffs": {
     "type": "array",
     "minItems": 1,
     "maxItems": 8,
     "items": {
      "type": "object",
      "required": [],
      "properties": {
       "address": {
        "type": "string",
        "description": "Street address; geocoded server-side if lat/lng omitted"
       },
       "lat": {
        "type": "number"
       },
       "lng": {
        "type": "number"
       },
       "contact_name": {
        "type": "string"
       },
       "contact_phone": {
        "type": "string"
       },
       "instructions": {
        "type": "string"
       },
       "window_start": {
        "type": "string",
        "format": "date-time"
       },
       "window_end": {
        "type": "string",
        "format": "date-time"
       },
       "proof_required": {
        "type": "array",
        "items": {
         "type": "string",
         "enum": [
          "photo",
          "signature",
          "recipient_name",
          "otp",
          "id_check"
         ]
        }
       }
      }
     }
    },
    "service": {
     "type": "string",
     "enum": [
      "auto",
      "local",
      "intercity"
     ],
     "default": "auto",
     "description": "auto picks intercity when the drop-off is in another launch city"
    },
    "speed": {
     "type": "string",
     "enum": [
      "express",
      "standard",
      "shared"
     ],
     "default": "standard",
     "description": "Intercity only: express = dedicated driver leaves w

Responses: 201 OK402 insufficient_funds — deposit first403 spending_cap422 outside_coverage / prohibited_item

GET/v1/deliveriesList deliveries🔑 key

Params: statussincelimitoffset

Responses: 200 OK

POST/v1/deliveries/batchCreate up to 25 deliveries🔑 key
{
 "type": "object",
 "properties": {
  "deliveries": {
   "type": "array",
   "items": {
    "allOf": [
     {
      "type": "object",
      "required": [
       "pickup",
       "dropoffs"
      ],
      "properties": {
       "pickup": {
        "type": "object",
        "required": [],
        "properties": {
         "address": {
          "type": "string",
          "description": "Street address; geocoded server-side if lat/lng omitted"
         },
         "lat": {
          "type": "number"
         },
         "lng": {
          "type": "number"
         },
         "contact_name": {
          "type": "string"
         },
         "contact_phone": {
          "type": "string"
         },
         "instructions": {
          "type": "string"
         },
         "window_start": {
          "type": "string",
          "format": "date-time"
         },
         "window_end": {
          "type": "string",
          "format": "date-time"
         },
         "proof_required": {
          "type": "array",
          "items": {
           "type": "string",
           "enum": [
            "photo",
            "signature",
            "recipient_name",
            "otp",
            "id_check"
           ]
          }
         }
        }
       },
       "dropoffs": {
        "type": "array",
        "minItems": 1,
        "maxItems": 8,
        "items": {
         "type": "object",
         "required": [],
         "properties": {
          "address": {
           "type": "string",
           "description": "Street address; geocoded server-side if lat/lng omitted"
          },
          "lat": {
           "type": "number"
          },
          "lng": {
           "type": "number"
          },
          "contact_name": {
           "type": "string"
          },
          "contact_phone": {
           "type": "string"
          },
          "instructions": {
           "type": "string"
          },
          "window_start": {
           "type": "string",
           "format": "date-time"
          },
          "window_end": {
           "type": "string",
           "format": "date-time"
          },
          "proof_required": {
           "type": "array",
           "items": {
            "type": "string",
            "enum": [
             "photo",
             "signature",
             "recipient_name",
             "otp",
             "id_check"
            ]
           }
          }
         }
        }
       },
       "service": {
        "type": 

Responses: 200 OK

GET/v1/deliveries/{id}Get a delivery (id or short code)🔑 key

Params: id

Responses: 200 OK

PATCH/v1/deliveries/{id}Update instructions / contingency / drop-off contact🔑 key

Params: id

{
 "type": "object",
 "properties": {
  "instructions": {
   "type": "string"
  },
  "contingency": {
   "type": "object"
  },
  "dropoff_contact": {
   "type": "object"
  },
  "window_end": {
   "type": "string"
  },
  "metadata": {
   "type": "object"
  }
 }
}

Responses: 200 OK

POST/v1/deliveries/{id}/fundFund from wallet and start dispatch🔑 key

Params: id

Responses: 200 OK402 insufficient_funds

POST/v1/deliveries/{id}/cancelCancel (free before a driver is assigned; 30% driver fee after)🔑 key

Params: id

{
 "type": "object",
 "properties": {
  "reason": {
   "type": "string"
  }
 }
}

Responses: 200 OK409 invalid_state (already picked up)

POST/v1/deliveries/{id}/confirmConfirm a delivered job and release payment (auto after 24h)🔑 key

Params: id

Responses: 200 OK

POST/v1/deliveries/{id}/tipTip the driver🔑 key

Params: id

{
 "type": "object",
 "required": [
  "amount_cents"
 ],
 "properties": {
  "amount_cents": {
   "type": "integer"
  }
 }
}

Responses: 200 OK

POST/v1/deliveries/{id}/rateRate the driver 1–5🔑 key

Params: id

{
 "type": "object",
 "required": [
  "stars"
 ],
 "properties": {
  "stars": {
   "type": "integer"
  },
  "comment": {
   "type": "string"
  }
 }
}

Responses: 200 OK

POST/v1/deliveries/{id}/disputeOpen a dispute (funds stay held)🔑 key

Params: id

{
 "type": "object",
 "required": [
  "reason"
 ],
 "properties": {
  "reason": {
   "type": "string"
  },
  "evidence": {
   "type": "array",
   "items": {
    "type": "string",
    "format": "uri"
   }
  }
 }
}

Responses: 201 OK

POST/v1/deliveries/{id}/returnCreate the reverse leg (return to pickup)🔑 key

Params: id

Responses: 201 OK

GET/v1/deliveries/{id}/messagesMessages with the driver🔑 key

Params: id

Responses: 200 OK

POST/v1/deliveries/{id}/messagesMessage the driver🔑 key

Params: id

{
 "type": "object",
 "required": [
  "body"
 ],
 "properties": {
  "body": {
   "type": "string"
  }
 }
}

Responses: 201 OK

Tracking

GET/v1/deliveries/{id}/trackLive status, ETA, driver position🔑 key

Params: id

Responses: 200 OK

GET/v1/deliveries/{id}/eventsEvent timeline; add ?stream=1 for SSE🔑 key

Params: idstream

Responses: 200 OK

GET/v1/deliveries/{id}/proofProof of delivery (signed photo URLs, signature, recipient)🔑 key

Params: id

Responses: 200 OK

GET/v1/events/streamSSE feed of every event on your account🔑 key

Responses: 200 text/event-stream

GET/v1/track/{code}Public recipient tracking by short code

Params: code

Responses: 200 OK

Wallet

GET/v1/walletBalance + recent ledger🔑 key

Responses: 200 OK

POST/v1/wallet/depositCard deposit via Stripe Checkout (returns a URL for a human to pay)🔑 key
{
 "type": "object",
 "required": [
  "amount_cents"
 ],
 "properties": {
  "amount_cents": {
   "type": "integer",
   "minimum": 500
  }
 }
}

Responses: 200 OK501 deposits_not_configured

POST/v1/x402/wallet/depositUSDC on Base via x402 (HTTP 402 flow; no human needed)🔑 key
{
 "type": "object",
 "properties": {
  "amountCents": {
   "type": "integer"
  }
 }
}

Responses: 200 OK402 Payment requirements (x402 v2)404 x402_not_enrolled

Webhooks

GET/v1/webhooksList webhooks🔑 key

Responses: 200 OK

POST/v1/webhooksRegister a webhook (HMAC-signed)🔑 key
{
 "type": "object",
 "required": [
  "url"
 ],
 "properties": {
  "url": {
   "type": "string",
   "format": "uri"
  },
  "events": {
   "type": "array",
   "items": {
    "type": "string"
   }
  }
 }
}

Responses: 201 OK

DELETE/v1/webhooks/{id}Remove webhook🔑 key

Params: id

Responses: 200 OK

Shopify

GET/v1/shopify/shopsShopify shops connected to this account🔑 key

Responses: 200 OK

GET/v1/shopify/ordersShopify orders seen by the app with their delivery status🔑 key

Params: statuslimit

Responses: 200 OK

POST/v1/shopify/orders/{ref}/bookBook a delivery for a Shopify order (by order name like #1001, order id, or our row id); fetches the order from Shopify if needed🔑 key

Params: ref

{
 "type": "object",
 "properties": {
  "force": {
   "type": "boolean",
   "description": "Ignore the shop's radius / size limits"
  },
  "shop": {
   "type": "string",
   "description": "myshopify domain when several shops are connected"
  }
 }
}

Responses: 200 Not booked — see order.status (skipped / needs_funds / failed) and order.last_error201 OK