curl -X POST 'https://api.cyclemate.club/reports/' \
-H 'apikey: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"issue_type": "road_closed",
"location": [-0.0766, 51.5323],
"description": "Carriageway closed for gas works, both directions",
"road_name": "Kingsland Road",
"source": "dft"
}'
{
"id": "6dd58bda-4c2e-4e6d-9b8b-2a41cf6f0e5a",
"status": "received",
"created_at": "2026-08-05T10:12:31.201Z"
}
Contributions
Submit a report
Send a road or infrastructure report and receive a report ID
curl -X POST 'https://api.cyclemate.club/reports/' \
-H 'apikey: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"issue_type": "road_closed",
"location": [-0.0766, 51.5323],
"description": "Carriageway closed for gas works, both directions",
"road_name": "Kingsland Road",
"source": "dft"
}'
{
"id": "6dd58bda-4c2e-4e6d-9b8b-2a41cf6f0e5a",
"status": "received",
"created_at": "2026-08-05T10:12:31.201Z"
}
Overview
Accepts a single report and returns a report ID immediately. A report is a categorised observation about a road at a coordinate. The report enters the processing pipeline (AI analysis plus human review). PollGET /reports/{id} for the outcome, typically available within 15 minutes.
Authentication
This endpoint requires an API key. Include it in theapikey header:
apikey: YOUR_API_KEY
Rate limits
User session tokens are limited to 60 reports per hour. Exceeding the limit returns429 with a Retry-After header and a retry_after_seconds field in the body. Partner API keys carry limits agreed at issuance. Contact us about expected volumes.
Request body
string
required
The report category. One of:
| Value | Meaning |
|---|---|
road_closed | The road is impassable: closure, street works, blockage. |
road_unsafe | A safety hazard: dangerous junction, surface hazard, conflict with motor traffic. |
bad_routing | We routed through here when a better route exists. |
unclear_instructions | A navigation instruction at this location was confusing or wrong. |
unpleasant | Rideable but unpleasant: rough surface, crowding, steep gradient. |
other | Anything else. Describe it in description. |
[number, number]
required
The report coordinate as
[longitude, latitude] (GeoJSON order, see Coordinate format).Optional parameters
Optional parameters
string
Free-text description of the issue, up to 2,000 characters. The more specific, the faster the analysis. Include what is blocked, since when, and until when if known.
string
Name of the affected road or place, up to 200 characters.
string
The sub-category, which says what kind of problem it is within the
issue_type. Sending one classifies the report without waiting for a human to read the description, so it is the single most useful optional field. Each category recognises its own values:issue_type | Recognised issue_subtype |
|---|---|
road_closed | private_locked, barrier_gate, no_cycling_zone, temporary_closure, permanent_closure, one_way, road_missing |
road_unsafe | poor_bike_lane, too_many_peds, too_many_vehicles |
bad_routing | faster_route, quieter_route, fewer_turns |
unclear_instructions | wrong_direction, unclear_instruction, missing_instruction |
unpleasant | cobbles_rough, too_hilly, too_many_peds |
other is accepted under every category. Under road_closed, the first five values mean the road is physically blocked and the last two mean the manoeuvre is illegal rather than the road impassable, which we act on differently. Any other string up to 64 characters is stored but is not classified.string
Required for partner API keys, ignored for user session tokens. The source identifier agreed when your key was issued (e.g.
dft, forest): a 2–32 character slug of a-z, 0-9, _, -. It attributes the submission and scopes which reports your key can read back.Response body
string
The report ID, a UUID string. Use it with
GET /reports/{id} to poll processing status.string
Always
received on creation.string
ISO 8601 timestamp of receipt.
curl -X POST 'https://api.cyclemate.club/reports/' \
-H 'apikey: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"issue_type": "road_closed",
"location": [-0.0766, 51.5323],
"description": "Carriageway closed for gas works, both directions",
"road_name": "Kingsland Road",
"source": "dft"
}'
{
"id": "6dd58bda-4c2e-4e6d-9b8b-2a41cf6f0e5a",
"status": "received",
"created_at": "2026-08-05T10:12:31.201Z"
}
Variants
Partner submission
A partner API key must send its agreedsource slug on every report. Submissions are attributed to that slug, and the key can read back any report submitted through the API.
User session submission
A signed-in user token submits withoutsource (any value sent is ignored). The report is attributed to the user’s account, and the token can read back only that user’s reports.
Error responses
400 Bad request
Invalid body: an unknownissue_type, an out-of-range location, or a missing source on a partner key. The error field names the problem.
{
"error": "issue_type must be one of: road_unsafe, road_closed, bad_routing, unclear_instructions, unpleasant, other"
}
401 Unauthorized
Missing or invalid credentials, or an anonymous caller.{
"error": "Endpoint requires one of: user, service"
}
405 Method not allowed
Method other thanPOST on the collection.
{
"error": "Method not allowed"
}
429 Too many requests
Rate limit exceeded, see Rate limits. Includes aRetry-After header.
{
"error": "Rate limit exceeded",
"retry_after_seconds": 45
}
500 Internal server error
Unexpected server failure.{
"error": "Internal server error"
}