# Rocket Car Rentals Vietnam — Partner API

**Integration guide, version 1.2 — 8 October 2026**

**Start here.** This is the orientation document for the pack: what the API is, how authentication
works, how rate codes behave, what must be agreed before live traffic, and the constraints that shape
everything else.

It deliberately does **not** repeat the fleet or location tables — those are `04-FLEET-CATALOGUE.md`
and `05-LOCATION-DIRECTORY.md`, generated from the same source data the API serves. Rental terms are
`06-RENTAL-TERMS.md`. Nothing here is a promise separate from the contract in `02-API-REFERENCE.md`
and `03-openapi.yaml`.

---

## 1. What the API is

A REST machine-to-machine distribution API. You shop, quote, book and cancel Rocket rentals under
your own credentials.

| | |
|---|---|
| **Base URL** | `https://rocketcarrentalsvietnam.com/api/partner/v1` |
| **Transport** | HTTPS only, TLS 1.2+ |
| **Format** | JSON or Rocket XML for business operations. Token endpoint remains form-encoded with JSON responses. |
| **XML namespace/schema** | `urn:rocket:partner-api:v1` · `partner-api.xsd` (also published as `/partner-api/pack/13-partner-api.xsd`) |
| **Contract** | OpenAPI 3.1 — see `openapi.yaml`; XML usage and samples are in `PROTOCOL_AND_XML.md` |
| **Version** | `v1`, in the path. A breaking change gets a new path, never a silent edit to this one. |

**Operations:** `GET /fleet`, `GET /fleet/{vehicleCode}`, `GET /locations`,
`GET /locations/{locationCode}`, `GET /rates`, `POST /availability`, `POST /quotes`,
`POST /reservations`, `GET /reservations`, `GET /reservations/{id}`,
`POST /reservations/{id}/cancel`.

**Two things to know before you design against it.**

1. **Availability is at the vehicle-model level, not the individual-car level.** Rocket offers a
   model in a city and does not reserve, guarantee or expose a specific physical vehicle. If your platform requires
   a decrementing count of physical units, tell us now — that is a change to how Rocket runs its
   fleet, not an API option.
2. **Reservations cannot be modified.** `PATCH /reservations/{id}` deliberately answers `501`.
   Cancel and re-book. We would rather refuse than pretend to support a partial amendment we cannot
   apply consistently.

---

## 2. Authentication

OAuth 2.0 client credentials (RFC 6749 §4.4). We issue you a `client_id` and `client_secret`; you
exchange them for a short-lived bearer token.

```
POST /api/partner/v1/oauth/token
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_id=...&client_secret=...
```

```json
{ "access_token": "<jwt>", "token_type": "Bearer", "expires_in": 600, "scope": "fleet:read locations:read ..." }
```

Send it as `Authorization: Bearer <token>` on every other call. Tokens last **10 minutes**; cache
and reuse one until it expires rather than minting per request. There is no refresh token — you
already hold credentials, so re-authenticate.

**Scopes** are granted per client and are the intersection of what your client and your partner
account hold: `fleet:read`, `locations:read`, `rates:read`, `availability:read`, `quotes:write`,
`reservations:read`, `reservations:write`, `reservations:cancel`. You will be given read and shop
scopes first, and booking scopes after a joint certification call.

**Errors** are always the same shape, and you should switch on `code`, never on `message`:

```json
{ "error": { "code": "INVALID_LOCATION", "message": "...", "requestId": "...", "retryable": false } }
```

Quote `requestId` to our support and we can find the exact call.

Business endpoints accept JSON or the Rocket XML representation. Send `Accept: application/xml` to
receive XML, and use `Content-Type: application/xml` for an XML request body. Both formats use the
same paths, OAuth scopes, validation schemas and business rules. The XML protocol is Rocket-specific:
it is not SOAP and does not claim OpenTravel/OTA compatibility. See `PROTOCOL_AND_XML.md` for the
mapping, curl example and XML safety rules. The OAuth token endpoint always remains form-encoded and
JSON.

**Money is never a bare number.** Every amount is an object with an integer in minor units:

```json
{ "currency": "USD", "amount": 43000, "exponent": 2, "display": "$430.00" }
```

**Reservation creation requires an `Idempotency-Key` header.** Retrying creation with the same key
returns the same reservation instead of creating a second one. Reuse of a key with a different body
is rejected. Cancellation does not require this header.

---

## 3. Fleet

The checked-in catalogue contains **49 vehicle models** across the four branch cities. `GET /fleet`
returns models that are currently published with a complete partner profile; use its response for
the live offerable set.

Every model carries a complete partner specification — doors, air conditioning, maximum passengers,
body type, drive type where known, transmission, fuel, a SIPP/ACRISS-style code, a refundable deposit
and a mileage policy. **The full table, with image URLs, is `04-FLEET-CATALOGUE.md`.** It is
generated from the same source data `GET /fleet` serves, and a CI test fails Rocket's build if the
two drift apart.

Three things worth knowing before you scope the mapping work:

- **The SIPP codes are Rocket-generated, not ACRISS-issued.** They follow the current ACRISS matrix,
  but **they are not ACRISS-issued model codes, and Rocket claims no ACRISS membership or
  certification.** If your contract requires centrally assigned ACRISS codes, tell us — that is a
  membership question, not a technical one. `04-FLEET-CATALOGUE.md` §2.2 explains how each character
  is derived.
- **Fourteen rows are provisional.** RC0021 Mercedes-Maybach S 500 and RC0037–RC0049 carry
  provisional fleet-profile details; see the individual entries below.
- **RC0037 Kia Cerato is provisional.** Its exact trim and model year still need physical-vehicle confirmation.
- **RC0038 Mazda CX8 is provisional.** Its drivetrain is intentionally unspecified until confirmation.
- **RC0039 Kia Sportage is provisional.** Its drivetrain is intentionally unspecified until confirmation.
- **RC0040 Mazda 2 is provisional.** Its exact trim and model year still need physical-vehicle confirmation.
- **RC0041 Toyota Vios is provisional.** Its exact trim and model year still need physical-vehicle confirmation.
- **RC0042 Hyundai Tucson is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0043 Honda CR-V (Crv) is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0044 VinFast VF 5 (Vf 5) is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0045 VinFast VF 9 (Vf 9) is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0046 VinFast VF 6 (Vf 6) is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0047 VinFast VF 7 (Vf 7) is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0048 VinFast Lux A is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- **RC0049 Hyundai Santa Fe (Santafe) is provisional.** Its exact trim, model year and drivetrain still need confirmation.
- The other 35 rows are fully evidenced.
- **Luggage capacity is not recorded** and returns `null`. We would rather return null than an
  estimate you would publish as fact.

**Deposits are USD 500 / 700 / 1,000 by vehicle class** and **mileage is 300 km/day with excess at
VND 5,000/km** on every vehicle. Read both per vehicle from the API rather than deriving them.

---

## 4. Locations

**Eight active stations across four cities** — one city station and one airport station per city.
Full detail, including branch street addresses, is `05-LOCATION-DIRECTORY.md`.

**The one thing to get right before you write any code:** `locationCode` and `iataCode` are
**different namespaces and are not interchangeable**. `HCM-APT` is a Rocket location code; `SGN`
is an IATA code. **Every request field takes the Rocket code.** City stations have no IATA code and
return `null` — that is correct data, not a gap.

Airport station addresses are `null` in the source. The API does not specify the physical hand-over
arrangement, delivery coverage, or a separate delivery price; confirm these in writing with Rocket
for each booking. The booking-pricing engine separately adds `locationSurcharge` of USD 14 per
airport or specific-location hand-over direction for rentals of 7 days or fewer (up to USD 28 when
both directions qualify; zero for longer rentals). This is not a delivery-coverage guarantee. See
`05-LOCATION-DIRECTORY.md` §6.
**Phu Quoc was withdrawn from the partner API on 21 August 2026** and Da Lat has never been active;
neither is returned by `GET /locations`.

**One-way rental** is supported between any two active stations and is priced as its own line item,
never folded into the rental total.

---

## 5. Rate and account codes

Rocket separates identity from price, which means you can build and certify the whole integration
before any commercial term is agreed.

| | |
|---|---|
| **Account code** | Who is buying. One per partner, issued with your credentials during onboarding. It carries no price. |
| **Rate code** | Which commercial rules apply. It carries no price either. |
| **Adjustment** | The only thing that changes a number, and it exists only after Rocket approves a specific figure. |

Use only account and rate codes confirmed for your partner. `GET /rates` returns the active codes
available to the authenticated account; verify the returned status and applicability before quoting.
Where no eligible partner rate is supplied, the API follows its documented default pricing behavior.

`GET /rates` returns the codes issued to *you*, and only to you.

Negotiated codes (including `RCNET`, `RCCOMM`, `RCCORP` and `RCPROMO`) require a matching active,
approved configuration for the authenticated partner. A code that is unavailable, inactive or not
approved is refused rather than silently treated as another rate.

**Commercial terms are issued by Rocket in a partner proposal**, not published here and not
encoded in the API.

**Commission is a commercial term, not an API behavior.** A commissionable code is usable only when
the corresponding configuration is active and approved for your account; otherwise the API returns
the applicable rate-plan error. Confirm your codes and quote behavior with Rocket during onboarding.

Your account code is issued at onboarding. If you tell us your own vehicle, location, account and
rate codes, we will record the mapping on our side so you can keep using your identifiers.

---

## 6. Agreement and onboarding

**Short answer: yes — an agreement is required before production activation, and not before you can
review or build against this specification.**

Four separate things, deliberately not bundled:

| Stage | Needed to | Status |
|---|---|---|
| **Technical specification** | Read, review, design and estimate | **Available now — this document, plus the full spec and `openapi.yaml`** |
| **Mutual NDA / data-protection terms** | Exchange traveller data | Required before any real booking. Vietnam's Law 91/2025/QH15 and Decree 356/2025/ND-CP apply; a draft addendum is `11-AGREEMENT-CHECKLIST.md`. |
| **Commercial and rate agreement** | Agree the commercial model, who is merchant of record, who owns refunds | **Not yet drafted.** See §8. |
| **Production credential activation** | Send live traffic | After all of the above, plus a joint certification call |

We do not have a signed template to send you today. If you would rather work from yours, send it —
you offered, and it is probably faster.

**Onboarding sequence:** agreement → we create your partner account and issue credentials → you
certify read and shop operations on your own schedule → a joint attended session for booking,
idempotent retry, and cancellation → we grant booking scopes → go live.

---

## 7. Environment — a scope-restricted production integration environment

**Rocket currently provides a scope-restricted production integration environment. An isolated
sandbox is not available.** Reservation certification is conducted during an attended session using
agreed test reservations that are cancelled immediately. Rocket's partnership proposal PDF offered
"API and sandbox access"; that statement is superseded.

**This integration credential accesses Rocket's live production fleet, location and pricing data.**
What you read through the API is the real catalogue at the real canonical price — not synthetic
inventory, not sample pricing, not an isolated copy.

**Safety comes from OAuth scope.** A credential carrying no `reservations:*` scope cannot create a
booking at all: the restriction below is what makes a production-pointed credential safe to hand out
on day one.

If an isolated test environment is a requirement on your side, tell us early. It means a second
database and a second Worker environment — new paid infrastructure and a product decision with cost
and lead time, not a switch Rocket can flip. It is tracked as open item O10 in `11-AGREEMENT-CHECKLIST.md`.

**During integration and UAT the credential is restricted from reservation operations by OAuth
scope.** It carries `fleet:read`, `locations:read`, `rates:read`, `availability:read` and
`quotes:write`, and no `reservations:*` scope at all. It can authenticate, read the whole fleet and
take real quotes; it cannot create, read, cancel or modify a reservation. Those calls return `403
INSUFFICIENT_SCOPE`.

**Reservation capability is activated separately, after joint integration approval.** Rocket's
preferred route is to issue a *new* Production Booking client at that point rather than widen the
integration one, so there is a clean audit boundary between the credential that could only look and
the credential that can book. The integration credential then stays restricted or is revoked.

## 8. What Rocket still needs to decide, and what we need from you

**Open on Rocket's side.** These do not block you reviewing or building against the specification.
They do block go-live, and several of them change what you would publish, so we are not hiding them:

- The commercial model, as set out in Rocket's partner proposal.
- Merchant of record, settlement and who carries FX.
- Who owns cancellation refunds and chargebacks, and who holds the refundable security deposit (USD 500 / 700 / 1,000 per vehicle, collected by Rocket at pickup).
- Tax and fee presentation.
- Support hours, response times and the notice period for a breaking API change.

**Settled on 21 August 2026** and no longer open: the cancellation schedule (free more than 24 hours
before pick-up, one day's rental fee within 24 hours), the security deposit (USD 500 / 700 / 1,000
per vehicle) and the mileage allowance (300 km/day, excess VND 5,000/km). Rocket's consumer-facing
terms were corrected on the same date so the website and this API now state the same figures.
`06-RENTAL-TERMS.md` carries the detail and lists what remains genuinely undecided.

**What we need from you.**

1. Confirmation that **model-level availability** is acceptable to your platform.
2. Whether a **permanently isolated test environment** is a hard requirement on your side (§7).
3. Your expected **look-to-book ratio** and peak request volume, so rate limits are sized before
   your first peak rather than after your first `429`.
4. Your **codes** for vehicles, locations, accounts and rates, so we can record the mapping.
5. Whether you need **webhooks** for booking status changes. **v1 has none** — poll
   `GET /reservations`. If webhooks are a hard requirement, say so now: it is a build, not a setting.
6. Your **tax breakdown and currency** requirements.
7. Your **draft agreement**, if you would like to start from it.

---

## Appendix — accompanying documents

| File | What it is |
|---|---|
| `02-API-REFERENCE.md` | The full technical contract: every endpoint, field, error code and worked example |
| `03-openapi.yaml` | OpenAPI 3.1 machine-readable schema — generate a client from this |
| `04-FLEET-CATALOGUE.md` | All 49 models: specifications, SIPP codes, deposits, mileage, image URLs |
| `05-LOCATION-DIRECTORY.md` | The eight active stations, branch addresses, and the locationCode/IATA distinction |
| `06-RENTAL-TERMS.md` | Rental terms for a partner reader |
| `07-CODE-MAPPING-WORKSHEET.md` | The mapping worksheet — fill in the right-hand column and send it back |
| `08-IMAGE-LICENCE.md` | Right to reproduce Rocket's vehicle photography on your own channels |
| `11-AGREEMENT-CHECKLIST.md` | Draft data-protection annex under Vietnam's 2026 framework, for your counsel to redline |
| `11-AGREEMENT-CHECKLIST.md` | **Every unsettled item in one register**, each with an owner and the gate it blocks, plus the contact matrix |
| `10-INTEGRATION-OPERATIONS.md` | How to raise a problem, polling reconciliation, what model-level free-sale means, amendment procedure, the certification test plan, station operations |
| `11-AGREEMENT-CHECKLIST.md` | What the API gives you to reconcile with, and the commercial questions still open |

**Contact:** see the contact matrix in `11-AGREEMENT-CHECKLIST.md` §6. Quote this document's version and date.
