Skip to main content
Use Route4Me through Corsair: one client, typed API calls. Copy the key from the Route4Me web app under Settings → Organization Settings → API Key. One key serves both API generations this plugin wraps, and it travels as the api_key query parameter. Things to know before you call:
  • Two hosts, two generations. Optimizations use the v4 API on api.route4me.com/api.v4; routes, orders, vehicles, the address book, customers and team users use the v5 API on wh.route4me.com/modules. Both are wrapped here, so a caller does not have to know which generation a resource lives on.
  • The v5 host needs Accept: application/json. wh.route4me.com also serves the web app, and a request that does not ask for JSON is redirected to the login page — even with a valid key. The plugin always sends that header. If you call this host yourself, send it too, or a rejected key looks like an HTML login page rather than a 401.
  • The error envelopes differ. v4 answers { errors: [...], error_code }; v5 answers { status: false, error, code, messages: [...] }. Route4MeAPIError.errors holds every message in both cases.
  • v5 validates with 406. A rejected field or filter comes back as 406, not 400, and the plugin treats it as a validation failure rather than a request that might succeed on a retry.
  • Two kinds of paging. The v5 collections page by page/per_page and return a meta block; next_page is derived from meta.current_page and meta.last_page. The address book pages by limit/offset and the plugin returns next_offset, which is null on a short page. v4 optimizations page by limit/offset with totalRecords.
  • optimizations.list accepts one or many. Passing optimization_problem_id makes v4 answer a single object instead of a collection; the plugin normalises both into the same optimizations array and reports total_records: 1. optimizations.get is the clearer call when you already have the id.
  • Creating an optimization is asynchronous. The solver queues the problem and returns an id with state: 0. Poll optimizations.get until state reaches 4 (Optimized); 5 is an error and 6 means directions are still being computed.
  • Coordinates are required for an address book contact. addresses.create needs cached_lat and cached_lng alongside the street address, because Route4Me will not geocode on write. An optimization stop, by contrast, takes either an address or a coordinate pair.
  • Choosing a stop type. address_stop_type takes one of DELIVERY, PICKUP, BREAK, MEETUP, SERVICE or VISIT; leaving it out lets Route4Me use the account default.
  • Order contact fields are renamed on the wire. orders.create sends first_name, last_name, email and phone as EXT_FIELD_first_name and so on, which is what the v5 API reads.
  • Retries. Route4Me documents no throughput window and no Retry-After, so a 429 is retried three times with exponential backoff. A 5xx is retried only for calls declared read-only: v5’s list routes are POSTs, so the HTTP method alone would misclassify them.
What you get:
  • 13 typed API operations

Setup

1

Install

2

Add the plugin

corsair.ts
With multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.
3

Choose authentication

4

Connect a tenant

Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.

Example API calls

List routes with page paging
Create a delivery order
See the full list on the API page.

What’s next

API reference

Every route4me.api.* operation with input and output types.

Connect / OAuth

createLink, Hub delivery, and tenant connect flows.

Use with agents

Expose this plugin’s operations as MCP tools.