Okouro docs

Two kinds of record describe a person. A user can sign in and has a role. A consultant is a staffable profile that carries a daily cost, a manager, and a status. Being able to track somebody’s time requires both, linked together: a consultant whose user_id points at a user.

This guide covers inviting people, accepting invitations, and creating consultant profiles - either linked to an existing user or inviting a brand-new one in a single step.

Roles needed

Inviting users and creating consultants requires an admin (or, for consultants, an operations user). The invitee accepts their own invitation without being signed in.

Invite a teammate

Create an invitation for an email and a role. The invitee gets a token (delivered by email in a real deployment) they use to accept.

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

{ "email": "ada@acme.com", "role": "consultant" }

Returns 201 Created with an InvitationResponse:

{
  "id": "0190a1c2-...",
  "account_id": "0190a1c2-...",
  "email": "ada@acme.com",
  "role": "consultant",
  "status": "pending",
  "expires_at": "2026-01-12T09:00:00Z"
}

List invitations with GET /invitations and cancel one with DELETE /invitations/{id} (204).

Accept an invitation

The invited person sets a password and their name using the invitation token. This is a public endpoint and it signs them in immediately.

POST /invitations/accept HTTP/1.1
Content-Type: application/json

{
  "token": "<invitation-token>",
  "password": "a-strong-password",
  "full_name": "Ada Lovelace"
}

Returns 201 Created with a full AuthResponse (see Authentication). The new user’s consultant_id is null until a consultant profile is linked. An expired token returns 410 Gone.

Create a consultant profile

A consultant can be created in two ways.

Use the user_id you obtained when the user signed up or accepted their invitation.

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

{
  "full_name": "Ada Lovelace",
  "user_id": "0190a1c2-...",
  "title": "Senior Engineer",
  "daily_cost": "450.00"
}

Invite a new user in the same call

Instead of user_id, pass invite_email (and optionally invite_role, default consultant). Okouro sends the invitation and links the consultant automatically once the invitation is accepted. user_id and invite_email are mutually exclusive.

{
  "full_name": "Ada Lovelace",
  "invite_email": "ada@acme.com",
  "title": "Senior Engineer"
}

Both return 201 Created with a ConsultantResponse:

{
  "id": "0190a1c2-...",
  "account_id": "0190a1c2-...",
  "full_name": "Ada Lovelace",
  "user_id": "0190a1c2-...",
  "user_email": "ada@acme.com",
  "manager_id": null,
  "manager_full_name": null,
  "title": "Senior Engineer",
  "daily_cost": "450.00",
  "picture": null,
  "status": "inactive"
}

Note daily_cost is null when the caller is a consultant-role token (see Roles and permissions).

Status

A consultant’s status is one of active, bench, or inactive:

  • inactive is what you set when creating a profile.
  • active is computed from the presence of active assignments.
  • bench is computed (an active consultant with no current assignment) and cannot be set directly.

On PUT /consultants/{id} you may only set active or inactive; sending bench is rejected.

Assign a manager

Set manager_id to a user id to make that user the consultant’s team leader. That user gains review powers over this consultant’s timesheets, time off, and expenses (see Roles and permissions).

Update and clear fields

PUT /consultants/{id} replaces the profile. Fields that represent links or uploads must be resent to be kept; omitting user_id, manager_id, or picture clears them. So when updating a name, echo back the existing user_id and manager_id you want to retain.

Find users not yet linked

GET /users/unbound lists users who have no consultant profile yet - the natural candidates to link when creating a consultant.

Profile pictures

picture is a data URL (data:<mime>;base64,<data>), capped at 5 MB raw. It is optional on both create and update.

Endpoints at a glance

ActionMethodPathSuccess
List invitationsGET/invitations200
InvitePOST/invitations201
Revoke invitationDELETE/invitations/{id}204
Accept invitationPOST/invitations/accept201
List consultantsGET/consultants200
Get consultantGET/consultants/{id}200
Create consultantPOST/consultants201
Update consultantPUT/consultants/{id}200
Delete consultantDELETE/consultants/{id}204
List unbound usersGET/users/unbound200

Once a consultant is linked and assigned to a mission, move on to Track time and Run a mission.