Create Shift
POST {{base_url}}/api/v3/shifts
Required scope: shifts:write
Creates an operator-owned shift. Requires admin credentials.
start, stop, and retreat_point are required. The retreat point and optional runner must belong to the caller’s operator. Shifts may be at most 12 hours; pay values must be non-negative and at most 10,000. A runner overlap returns 409.
Idempotency-Key is optional but strongly recommended for programmatic retries. Reuse a key only for the identical request. Concurrent use of the same key can return 409; retry with backoff.
Request body
Section titled “Request body”{ "start": "2026-10-20T13:00:00.000Z", "stop": "2026-10-20T17:00:00.000Z", "retreat_point": "{{RETREAT_POINT_ID}}", "role": "car", "user_id": "{{RUNNER_ID}}", "hourly_rate": 20, "bonus_pay": 10, "dedicated_vendor_id": null}Examples
Section titled “Examples”curl --request POST '${base_url}/api/v3/shifts' \ --header 'Content-Type: application/json' \ --header 'Idempotency-Key: {{IDEMPOTENCY_KEY}}' \ --data '{ "start": "2026-10-20T13:00:00.000Z", "stop": "2026-10-20T17:00:00.000Z", "retreat_point": "{{RETREAT_POINT_ID}}", "role": "car", "user_id": "{{RUNNER_ID}}", "hourly_rate": 20, "bonus_pay": 10, "dedicated_vendor_id": null}'const response = await fetch("${base_url}/api/v3/shifts", { "method": "POST", "headers": { "Content-Type": "application/json", "Idempotency-Key": "{{IDEMPOTENCY_KEY}}" }, "body": "{\n \"start\": \"2026-10-20T13:00:00.000Z\",\n \"stop\": \"2026-10-20T17:00:00.000Z\",\n \"retreat_point\": \"{{RETREAT_POINT_ID}}\",\n \"role\": \"car\",\n \"user_id\": \"{{RUNNER_ID}}\",\n \"hourly_rate\": 20,\n \"bonus_pay\": 10,\n \"dedicated_vendor_id\": null\n}"})const data = await response.json()import requests
response = requests.request( "POST", "${base_url}/api/v3/shifts", headers={ 'Content-Type': 'application/json', 'Idempotency-Key': '{{IDEMPOTENCY_KEY}}'}, data="{\n \"start\": \"2026-10-20T13:00:00.000Z\",\n \"stop\": \"2026-10-20T17:00:00.000Z\",\n \"retreat_point\": \"{{RETREAT_POINT_ID}}\",\n \"role\": \"car\",\n \"user_id\": \"{{RUNNER_ID}}\",\n \"hourly_rate\": 20,\n \"bonus_pay\": 10,\n \"dedicated_vendor_id\": null\n}",)response.raise_for_status()Saved responses
Section titled “Saved responses”{ "type": "success", "data": { "id": "550e8400-e29b-41d4-a716-446655440000", "retreat_point": "650e8400-e29b-41d4-a716-446655440000", "territory_id": "850e8400-e29b-41d4-a716-446655440000", "operator_id": 123, "start": "2026-10-20T13:00:00.000Z", "stop": "2026-10-20T17:00:00.000Z", "user_id": "1697c3af-450f-42f4-8609-669a4350c22f", "role": "car", "hourly_rate": 20, "bonus_pay": 10, "checked_in": null }}{ "type": "error", "message": "Shift not found", "status": 404}{ "type": "error", "message": "Shift overlaps another shift for this rider", "status": 409}{ "type": "error", "message": "start must be before stop", "status": 400}
