Okouro docs

Delivery hangs off one chain: a client owns missions, a mission staffs consultants through assignments, and each mission carries a budget you can measure against actuals. This guide walks the whole chain in order.

1. Create a client

POST /clients HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{ "name": "Acme Corp", "status": "customer", "industry": "Manufacturing" }

Returns 201 Created with a ClientResponse. status is prospect or customer (defaults to customer). Keep the returned id.

2. Open a mission

A mission belongs to a client and moves through draft, active, completed, or cancelled.

POST /missions HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "client_id": "0190a1c2-...",
  "name": "Apollo",
  "start_date": "2026-01-01",
  "end_date": "2026-06-30"
}

Returns 201 Created with a MissionResponse. Update it with PUT /missions/{id}, which also takes the status you want to move it to.

3. Assign a consultant

An assignment links a consultant to a mission over a date range, with an optional billing rate. See Manage people to create the consultant.

POST /assignments HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "mission_id": "0190a1c2-...",
  "consultant_id": "0190a1c2-...",
  "start_date": "2026-01-01",
  "billing_rate": "900.00"
}

Returns 201 Created with an AssignmentResponse. status is active, completed, or cancelled. The billing_rate comes back as null for consultant-role callers (see Roles and permissions). An active assignment is what turns a consultant’s status to active and unlocks timesheet lines for them (see Track time).

4. Set the budget

A budget declares the sale mode and planned revenue/cost. Only an admin can set it.

PATCH /missions/{id}/budget HTTP/1.1
Authorization: Bearer <access_token>
Content-Type: application/json

{
  "sale_mode": "time_and_materials",
  "budget_revenue": "100000.00",
  "budget_cost": "60000.00"
}

sale_mode is time_and_materials (default) or fixed_price.

5. Read the budget against actuals

GET /missions/{id}/budget HTTP/1.1
Authorization: Bearer <access_token>

Returns a MissionBudgetResponse that compares plan, actuals, and forecast:

{
  "sale_mode": "time_and_materials",
  "health": "on_track",
  "reasons": [],
  "progress_percent": 42.0,
  "budget":   { "revenue": "100000.00", "cost": "60000.00", "margin": "40000.00" },
  "actuals":  { "revenue": "41000.00", "cost": "25000.00", "margin": "16000.00" },
  "forecast": { "revenue": "98000.00", "cost": "59000.00", "margin": "39000.00" },
  "variance": { "revenue": "-2000.00", "cost": "-1000.00", "margin": "-1000.00" },
  "days_worked": "46"
}

health is unknown, on_track, at_risk, or over. cost and margin are null for consultant-role callers; revenue is always visible. To compare several missions at once, use GET /kpi/mission-budgets?ids=... (see Read KPIs).

Endpoints at a glance

ActionMethodPathSuccess
Create clientPOST/clients201
List / get clientsGET/clients, /clients/{id}200
Create missionPOST/missions201
Update missionPUT/missions/{id}200
Create assignmentPOST/assignments201
Update assignmentPUT/assignments/{id}200
Set budgetPATCH/missions/{id}/budget200
Read budgetGET/missions/{id}/budget200

With assignments in place, the day-to-day flows Track time and Manage expenses both attach to the mission.