# REST API Reference

Base URL:

```text
https://app.keito.ai/api/v2
```

API v2 is Harvest-compatible: request and response fields use `snake_case`, dates use `YYYY-MM-DD`, and paginated collections include entity-specific array keys such as `time_entries`, `projects`, `tasks`, and `expenses`.

## Authentication

API key requests require both headers:

```text
Authorization: Bearer kto_xxxxx
Keito-Account-Id: your_company_id
```

Find the Company ID in Keito under **Settings -> API & Developers -> Company ID**.

WorkOS Connect JWT requests do not need `Keito-Account-Id`; the company is resolved from token claims.

## Conventions

- **Dates**: `YYYY-MM-DD` for dates. Report endpoints also accept Harvest-style `YYYYMMDD`.
- **IDs**: Keito returns database IDs such as `cm...`; do not assume IDs use short prefixes like `prj_` or `co_`.
- **Pagination**: collection endpoints use `page` and `per_page`. Responses include `page`, `per_page`, `total_pages`, `total_entries`, and `links`.
- **Source**: `source` can be `web`, `cli`, `api`, or `agent`.
- **Metadata**: `metadata` must be a JSON object and is limited to 4KB.

## Endpoints

| Method | Endpoint | Description |
|---|---|---|
| `GET` | `/api/v2/users/me` | Current authenticated user and company |
| `GET` | `/api/v2/projects` | List projects |
| `GET` | `/api/v2/tasks` | List tasks |
| `GET` | `/api/v2/time_entries` | List time entries |
| `POST` | `/api/v2/time_entries` | Create a time entry |
| `PATCH` | `/api/v2/time_entries/:id` | Update a time entry |
| `PATCH` | `/api/v2/time_entries/:id/stop` | Stop a running time entry |
| `DELETE` | `/api/v2/time_entries/:id` | Delete a time entry |
| `GET` | `/api/v2/expenses` | List expenses |
| `POST` | `/api/v2/expenses` | Create an expense |
| `GET` | `/api/v2/clients` | List clients |
| `POST` | `/api/v2/clients` | Create a client |
| `GET` | `/api/v2/contacts` | List contacts |
| `POST` | `/api/v2/contacts` | Create a contact |
| `GET` | `/api/v2/invoices` | List invoices |
| `POST` | `/api/v2/invoices` | Create an invoice |
| `GET` | `/api/v2/reports/time/team` | Team time report |

## Common Query Parameters

| Parameter | Type | Description |
|---|---|---|
| `page` | number | Page number, starting at `1` |
| `per_page` | number | Results per page, default `100`, max `2000` |
| `source` | string | Filter by source: `web`, `cli`, `api`, `agent` |
| `project_id` | string | Filter by project |
| `task_id` | string | Filter by task |
| `user_id` | string | Filter by user |
| `client_id` | string | Filter by client |
| `from` | string | Start date |
| `to` | string | End date |
| `updated_since` | string | ISO timestamp lower bound |

## Example

```bash
curl "https://app.keito.ai/api/v2/time_entries?from=2026-05-01&to=2026-05-31" \
  -H "Authorization: Bearer kto_xxxxx" \
  -H "Keito-Account-Id: your_company_id"
```