Skip to content

Getting started: from zero to the first booking

7 min read

This page provides a step-by-step checklist for developers integrating with Ferry from initial setup to issuing the first ferry ticket. Following these steps sequentially ensures smooth integration and prevents service disruption.

The diagram below illustrates the 10-step journey from preparation to your first ticket:

flowchart TB
subgraph prep["Preparation Phase"]
s1["1. Identify organization in hierarchy"]
s2["2. Receive API key from admin"]
s3["3. Store key securely and set header"]
s4["4. Select environment and get base URL"]
end
subgraph query["Data Retrieval Phase"]
s5["5. Test voyage search call"]
s6["6. Fetch seat layout and availability"]
s7["7. Verify pricing and vouchers"]
end
subgraph trans["Transaction Phase"]
s8["8. Top up agency deposit balance"]
s9["9. Create reservation booking"]
s10["10. Confirm ticket issuance and track status"]
end
s1 --> s2 --> s3 --> s4 --> s5 --> s6 --> s7 --> s8 --> s9 --> s10

Step 1 — Identify your organization’s position in the agency hierarchy

Section titled “Step 1 — Identify your organization’s position in the agency hierarchy”

What to do: Contact your Ferry representative to verify your agency organization details in the system. Clearly identify your direct parent organization to understand pricing policies, markup tiers, and bank account details for balance top-ups.

Done when: You know your organization ID, your direct parent organization, and the net pricing terms applicable to your agency.

Step 2 — Obtain an API key from your agency administrator

Section titled “Step 2 — Obtain an API key from your agency administrator”

What to do: Partners cannot create keys via API. An agency user with the admin role must sign in to the web Dashboard, navigate to Settings > API Keys, generate a new key, and securely transfer it to the technical team. For detailed instructions, see API Key Management on Dashboard.

Done when: You possess the complete API key string. This key is displayed only once upon creation and cannot be retrieved later.

Keys are issued only to organizations with a partnership contract. Keys do not expire automatically; revocation is an immediate, irreversible hard deletion.

Step 3 — Store the key securely and configure authentication headers

Section titled “Step 3 — Store the key securely and configure authentication headers”

What to do: Store the API key in a secure server-side secrets store or environment variable. Configure your HTTP client to attach the Authorization: Bearer <API_KEY> header to every outbound call to Ferry.

Done when: Your backend service reads the key from environment variables. The key string must never be committed to source code repositories or exposed in client-facing applications.

Ferry reads the key only through Authorization; X-API-Key has no effect. Keep the key out of logs and variables embedded into client builds.

Step 4 — Choose your environment and confirm the base URL

Section titled “Step 4 — Choose your environment and confirm the base URL”

What to do: Request the official UAT base URL in writing from the Ferry team. Note the vital caveat: the UAT environment connects to live operator ticketing engines and issues real tickets. Agree in advance on which specific voyage to test with Ferry to prevent unwanted ticketing charges.

Done when: You hold the confirmed test environment base URL and an approved test voyage list.

CangSaKy still places real bookings even when real-ticket issuance mode is disabled for the environment. Agree with Ferry on the operator, voyage, and party responsible for each test’s costs.

What to do: Send a GET request to the Voyages group searching for ferry sailings by departure terminal, arrival terminal, and departure date.

Done when: You receive an HTTP 200 response with an active list of real voyages. If you receive an HTTP 401, verify the Authorization header name and the Bearer prefix.

HTTP 200 with an empty list can hide a system failure; it does not prove there are no voyages. Try a pier pair and date known to have data before concluding. Sorting by fields other than _id falls back to descending _id; see Conventions.

Step 6 — Fetch seat layouts and seat availability

Section titled “Step 6 — Fetch seat layouts and seat availability”

What to do: Using the voyage ID obtained in the previous step, call the Boat Layout group to retrieve cabin seating charts and the Voyage Counts group to check remaining seat counts per cabin class.

Done when: You have detailed information about valid vacant seat codes ready to submit in an order.

Availability changes continuously. Query Ferry again immediately before creating the booking; do not rely on a long-cached layout or derive remaining capacity yourself.

What to do: Call the Ticket Price Additions group to review applicable surcharges or markup rules, and the Vouchers group to validate discount codes (if applicable).

Done when: You know both the retail price charged to end customers and the agency NET amount payable to your direct parent organization.

What to do: Inspect your current balance via the Transactions or Debt Ledgers groups. Transfer funds following your parent organization’s payment instructions so that your available balance meets or exceeds the total order value.

Done when: Your agency’s available balance is sufficient to cover the order cost. Balance deduction occurs upon ticket confirmation.

What to do: Call the Bookings group with voyage details, selected seat positions, and passenger identity details to create a tentative booking.

Done when: You have saved the booking ID, Requested status (2), Unpaid payment status (1), and payment_expired_at. Seats are marked within Ferry only, not reserved on the operator system.

Step 10 — Confirm ticket issuance and track status

Section titled “Step 10 — Confirm ticket issuance and track status”

What to do: Call POST /bookings/confirmToIssue/{id}, then poll GET /bookings/{id} to confirm the outcome. Webhooks are signals only: they have no signature, no retries, and a 2-second timeout. Do not replace polling with webhook delivery.

Done when: The booking reaches Issued status (10); then download the tickets for the customer.

Confirmation can take 5–8 minutes with some operators. A timeout does not prove failure, and an in-progress error is not a reason to cancel. A paid booking may automatically reach status 10 after several minutes through background reconciliation. Do not rush to cancel or create a replacement; consult Booking flow and Rate limits before retrying.

StepLocationRelevant API groupDone when
1Ferry liaisonNone (offline)Parent organization and pricing tier confirmed
2Agency DashboardNone (offline)Valid API key received
3Your serverNone (offline)Key stored in secret store with Bearer header set
4Ferry liaisonNone (offline)UAT base URL and approved test voyage confirmed
5Your serverVoyagesReal voyage list received (HTTP 200)
6Your serverBoat Layout, Voyage CountsSeat layout and valid vacant seats retrieved
7Your serverTicket Price Additions, VouchersRetail and wholesale pricing determined
8Bank transferTransactions, Debt LedgersAvailable balance sufficient for order value
9Your serverBookingsBooking created with seat hold timestamp
10Your serverBookingsTicket issuance confirmed and e-tickets received
MisconceptionRealityCorrect practice
Issuing test tickets freely in UATUAT connects to live operators and incurs real costsOnly test ticketing on voyages explicitly agreed with Ferry
Automatically retrying timed-out booking callsBooking creation lacks automated deduplicationCheck recent bookings before deciding to retry
Expecting balance deduction upon booking creationBalance is only deducted upon ticket confirmationEnsure balance is sufficient before triggering confirmation
Confusing retail prices with agency settlement pricesDifferent amounts depending on markup configurationsAlways verify pricing via calculation APIs before checkout

The API groups required for these 10 steps are mapped on the Scalar UI — Ferry VN API:

Workflow stepScalar group
Step 5: Voyage searchVoyages
Step 6: Seat layout and countsBoat Layout, Voyage Counts
Step 7: Price additions and vouchersTicket Price Additions, Vouchers
Step 8: Balances and debt ledgersTransactions, Debt Ledgers
Steps 9 and 10: Booking and ticketingBookings, Orders
GuideRecommended next reading
EnvironmentsRead operational differences and testing rules for UAT
Authentication with an API keyKey format, lifecycle, and safe rotation procedures
Voyage and seat lookupDetailed guide on schedule search and seat layouts
Bookings: the life cycle of one bookingIn-depth order handling workflow from creation to completion