Matching
How RideWiseCore picks an agent, runs the offer cycle, and escalates on decline or timeout.
A match is one request to find an agent for one pickup. You create it with POST /matches. RideWiseCore then offers the ride to agents one at a time, nearest first, until one accepts or no candidates are left.
Match statuses
| Status | Meaning | Final? |
|---|---|---|
searching | An offer is out to an agent, waiting for an answer | No |
matched | An agent accepted. See matchedAgentId | ✅ Yes |
unmatched | No eligible agent accepted within the search radius | ✅ Yes |
cancelled | You cancelled it while it was still searching | ✅ Yes |
┌──── decline / 15 s timeout ────┐
▼ │
POST /matches ─▶ searching ── offer to next agent ┘
│ │
accept ◀──┘ └──▶ no more candidates ──▶ unmatched
│
▼
matched POST /matches/{id}/cancel ──▶ cancelledWho is eligible
For each match, RideWiseCore looks at up to the 50 nearest agents within radiusMeters of the pickup, closest first. An agent is offered the ride only if all of these are true:
- Their
statusisavailable. - Their
vehicleTypeexactly matches the requestedvehicleType. - They sent a location in the last 30 seconds (see freshness).
- They haven't already been offered this match.
- They're not currently holding an offer for another match.
That last rule matters when you're busy. Two matches created at the same moment never offer the same agent at the same time.
The offer cycle
-
RideWiseCore reserves the best candidate and sends a
ride:offerevent to your socket:{ "matchId": "9f1c2d4e-6b7a-4c3d-8e9f-0a1b2c3d4e5f", "agentId": "agt_1001", "pickup": { "lat": 40.713, "lng": -74.0055 }, "vehicleType": "sedan", "expiresInMs": 15000 } -
Your backend forwards the offer to that agent's app.
-
The agent has 15 seconds to respond. Your backend relays the answer with
ride:respond:- accept → the match becomes
matched, the agent is set tobusy, and you receivematch:update. - decline → the next-nearest eligible agent gets an offer right away.
- no answer → after 15 seconds (plus up to ~1 second of processing), the offer expires and moves to the next agent.
- accept → the match becomes
-
If no eligible agents are left, the match becomes
unmatchedand you receivematch:update.
Exactly one outcome wins for every offer. If an agent's accept arrives at the same moment as the timeout or your cancel, only one of them takes effect. If the agent's answer lost the race, ride:respond acknowledges with { ok: false, error: "Offer is no longer active" }. Tell that agent the offer is gone.
Creating a match
curl -X POST "$RWC_API_URL/matches" \
-H "Authorization: Bearer $RWC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"pickup": { "lat": 40.713, "lng": -74.0055 },
"vehicleType": "sedan",
"radiusMeters": 5000
}'The response reflects the match after the first candidate search:
status: "searching"with acurrentCandidateAgentId: an offer is already out.status: "unmatched": no eligible agent was found at all, so you can tell the passenger right away.
The first ride:offer can reach your socket before the HTTP response arrives. Key your offer handling by matchId, and don't assume the POST /matches response always comes first.
Following a match
Use either or both:
- Push: listen for
match:updateon your socket. It fires when a match becomesmatched,unmatchedorcancelled. - Poll:
GET /matches/{matchId}returns the current record at any time.
Cancelling
Cancel a match while it's searching, for example when the passenger gives up:
curl -X POST "$RWC_API_URL/matches/$MATCH_ID/cancel" \
-H "Authorization: Bearer $RWC_API_KEY"Any outstanding offer is withdrawn and the agent's reservation is released. If the match has already finished, you get 409 Conflict. If an accept, decline or timeout is being processed at that moment, you also get 409 with retry shortly. Retry after a brief pause.
After a match is matched, cancelling the ride is part of your own trip logic. RideWiseCore doesn't track trips. Remember to send the agent's status back to available.
Choosing a radius
| Setting | Value |
|---|---|
| Default | 10,000 m (10 km) |
| Maximum | 50,000 m (50 km) |
A smaller radius gives shorter pickups but more unmatched results in quiet areas. Some platforms retry an unmatched request once with a larger radius before telling the passenger no agent is available.
Billing
Each plan includes a monthly allowance of matches. Only matches an agent accepts count: unmatched and cancelled requests are free, and offering one request to several agents still counts once. Extra matches are billed per started block of 10, starting with October 2026 usage. See Billing & Plans.