Integration reference
Authentication
client_id and client_secret; you exchange them for a short-lived bearer token and send it as Authorization: Bearer <token> on every other call.Token request
The token endpoint is the one exception to JSON: it is form-encoded, per OAuth, not JSON.
POST /api/partner/v1/oauth/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRETcurl -sX POST https://rocketcarrentalsvietnam.com/api/partner/v1/oauth/token \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'grant_type=client_credentials' \
-d 'client_id=YOUR_CLIENT_ID' \
-d 'client_secret=YOUR_CLIENT_SECRET'A successful response:
{
"access_token": "<jwt>",
"token_type": "Bearer",
"expires_in": 600,
"scope": "fleet:read locations:read rates:read availability:read quotes:write"
}Tokens last 600 seconds (10 minutes). Cache and reuse one until it expires rather than minting per request. There is no refresh token — RFC 6749 §4.4.3 says a client-credentials response should not include one, since you already hold credentials and can re-authenticate at any time.
Send the token on every other call:
GET /api/partner/v1/fleet
Authorization: Bearer <access_token>Scopes
A token carries exactly the scopes granted to it, and no more. That grant is the intersection of what your API client and your partner account both hold — a scope missing from either side is missing from the token. You will be given read and shop scopes first, and booking scopes after a joint certification call.
fleet:read- Read the vehicle catalogue.
locations:read- Read rental locations.
rates:read- Read your own account and rate codes.
availability:read- Shop for offerable vehicles.
quotes:write- Request a priced quote.
reservations:read- Read your own reservations.
reservations:write- Create reservations.
reservations:cancel- Cancel your own reservations.
Errors
Every error, on every operation except the token endpoint, has this shape. Switch on code, never on message — messages may be reworded, codes will not change meaning within v1.
{
"error": {
"code": "INVALID_LOCATION",
"message": "The location code is unknown or not active.",
"requestId": "3f1c9e4a-0000-4000-8000-000000000000",
"retryable": false
}
}requestId is the fastest route to support: quote it and Rocket can find the exact call. retryable is true only when retrying the identical request may succeed. The full code table is on the /developers/reference page.
The token endpoint is different
POST /oauth/token uses the standard OAuth error shape, {"error", "error_description"}, because that is what OAuth clients parse — not the envelope above.Money
Every amount in this API is an object, never a bare number, with an integer in minor units:
{ "currency": "USD", "amount": 43000, "exponent": 2, "display": "$430.00" }Parse amount/exponent for arithmetic; use display only for rendering. Do not treat amount as a decimal value — 43000 here is $430.00, not $43,000.
Idempotency
Every booking write requires an Idempotency-Key header: 8–200 characters, unique per reservation attempt. A UUID is ideal.
POST /api/partner/v1/reservations
Authorization: Bearer <access_token>
Content-Type: application/json
Idempotency-Key: 6b1f6b0a-2f2a-4e7a-9b0a-8e2c9a6d5a11
{ "...": "reservation payload" }Retrying with the same key and the same body returns the same reservation — it never creates a second one. Reusing a key with a different body is rejected with 409 IDEMPOTENCY_CONFLICT. Full retry semantics, including the in-flight case, are on the /developers/reference page.