# Eos API v1

The Eos API v1 is the target contract for private, organization-specific integrations. It gives licensed API Clients programmatic access to Eos records, Agents, conversations, reports, and events while applying the same Eos Role and business-rule fences used throughout the product.

> **Status:** Design target. These endpoints are not available until the corresponding v1 implementation is released. Existing internal `/api/**` application routes are not part of this contract.

## Design goals

- A stable API at `https://api.eoshq.com/v1` that is independent of Eos frontend routes.
- Private API Clients created and controlled by an Eos organization administrator.
- OAuth 2.0 Client Credentials authentication for confidential server applications.
- Organization-wide record access constrained by the API Client's assigned Eos Roles.
- Deterministic authorization for direct API operations, Agent Skills, and Eos Chat.
- Machine-readable schemas, predictable errors, idempotent writes, and auditable execution.
- A contract suitable for developers and coding LLMs without requiring an MCP server.

## Supported API families

| API | Purpose | Initial access |
|---|---|---|
| [Authentication](authentication.html) | Provision licensed API Clients and obtain access tokens | Admin setup; client token exchange |
| [Organization](organization.html) | Read the organization attached to the client | Read-only |
| [Members](members.html) | Resolve active organization members for subject-aware workflows | Read-only |
| [Projects](projects.html) | List, create, update, and archive projects | Read/write by Role |
| [Tasks](tasks.html) | Manage project work, state, assignment, notes, and dependencies | Read/write by Role |
| [Time entries](time-entries.html) | Import and manage time records and submission state | Read/write by Role |
| [Tickets](tickets.html) | Manage tickets, replies, assignment, and status | Read/write by Role |
| [Invoicing](invoicing.html) | Manage draft invoices, lines, sending, payments, and collections | Finance/Manager |
| [Files](files.html) | Register uploads and access stored files | Read/write by Role |
| [Reports](reports.html) | Discover and run reports and retrieve exports | Read/run by Role |
| [Approvals](approvals.html) | Observe approval requests and decisions | Read-only for API Clients |
| [Integration connections](integration-connections.html) | Inspect organization connection readiness | Read-only |
| [Agents](agents.html) | Discover runnable Agents and create runs | Execute by compatible Role |
| [Runs](runs.html) | Observe, stream, continue, and cancel asynchronous work | Run owner by Role |
| [Conversations](conversations.html) | Maintain Eos Chat conversations and messages | Read/write by Role |
| [Custom fields](custom-fields.html) | Discover and use organization-defined fields on Eos objects | Read/write with the containing object |
| [Webhooks](webhooks.html) | Subscribe the client to Eos events and inspect deliveries | Own client only |

## APIs deliberately excluded from v1

The first version does not expose:

- API Client, license, billing, subscription, or organization-owner management.
- Provider administration or Eos operator functions.
- User impersonation.
- Agent creation, compilation, blueprint internals, or scheduling.
- Raw model prompts, chain-of-thought, internal routing, or unsanitized runtime logs.
- Personal Gmail, calendar, Slack, Microsoft, or other member-scoped provider credentials.
- Creation of new object types. Eos supports custom fields on existing objects, not custom objects.
- Formal approval decisions made by an API Client.
- Internal schedulers, Cloud Tasks handlers, provider callbacks, or existing internal application endpoints.

## Authentication model

Each API Client is a licensed, non-human Eos principal fixed to one organization. It receives a Regular or Manager license and one or more permitted Eos Roles.

| License | Assignable API Client Roles |
|---|---|
| Regular | Member |
| Manager | Member, Manager, Finance, HR |

Admin, Owner, provider, and internal Roles cannot be assigned to API Clients. Business and Enterprise organizations include one Manager-level API Client. Every additional API Client consumes an additional Regular or Manager license selected by the administrator.

Authentication uses the OAuth 2.0 Client Credentials grant with the coarse `eos.api` scope. Business permissions do not come from OAuth scopes; they come from the API Client's current Eos license, Roles, module access, metadata policy, and workflow rules.

See [Authentication and API Clients](authentication.html).

## Authorization model

An API Client has organization-wide record visibility only where its Eos Roles permit the object and operation. Project membership and assignment-based row filters do not restrict the client, but the following still apply:

- License validity and organization subscription status.
- Eos Role and Skill role fences.
- Object, field, module, and metadata access.
- Workflow state, required confirmation, and business validation.
- Principal-type restrictions that prohibit billing, security, licensing, and control-plane administration.

Changing a client's Roles or disabling its license takes effect without credential rotation.

## Member subjects and “my” operations

An Agent run, conversation, or supported operation may identify a member subject:

```json
{
  "subject": {
    "member_id": "alice@example.com"
  }
}
```

An Eos member ID is the member's normalized email address; v1 does not invent a second opaque identifier for a member. The API Client remains the actor, and the member is only the subject. Subject selection never grants the member's permissions, uses the member's personal provider tokens, or records the action as performed by that member.

Each operation and Skill must explicitly declare whether it accepts a member subject.

## Request conventions

### Base URL

```text
https://api.eoshq.com/v1
```

### Headers

```http
Authorization: Bearer ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
X-Client-Request-Id: your-correlation-id
Idempotency-Key: required-for-supported-writes
```

Eos returns `X-Request-Id` on every request. Include it in support requests.

### JSON and names

- Request and response field names use `snake_case`.
- IDs are opaque strings and must not be parsed.
- Timestamps use RFC 3339 UTC strings, for example `2026-08-22T10:30:00Z`.
- Date-only business fields use `YYYY-MM-DD`.
- Money uses decimal strings plus ISO 4217 currency codes; never binary floating point.
- Unknown response fields must be ignored to allow additive evolution.

### List envelopes

```json
{
  "object": "list",
  "data": [],
  "has_more": false,
  "next_cursor": null
}
```

List endpoints accept `limit` and `after`. The default limit is 50 and the maximum is 200 unless a page states otherwise. Cursors are opaque.

### Filtering and sorting

Filters use explicit query parameters documented by each API. `sort` accepts a supported field name and `order` is `asc` or `desc`. Unsupported filters return a validation problem; they are never silently ignored.

### Optimistic concurrency

Mutable resources return an `ETag`. Updates to an existing resource accept `If-Match`. A stale version returns `412 Precondition Failed`.

### Idempotency

Every `POST` documented as idempotent accepts `Idempotency-Key`. The key is scoped to the API Client and operation. Reusing a key with different input returns `409 Conflict`. Eos retains keys for at least 24 hours.

### Asynchronous operations

Long-running operations return `202 Accepted` with a [Run](runs.html) or job resource. Clients may poll, use server-sent events, or subscribe to webhooks.

## Errors

Errors use `application/problem+json`:

```json
{
  "type": "https://eoshq.com/problems/role-not-permitted",
  "title": "Role does not permit this operation",
  "status": 403,
  "detail": "The Finance Role is required to send this invoice.",
  "code": "ROLE_NOT_PERMITTED",
  "request_id": "req_01J8Q5A0MRV6Q7T1YVZ45JDF3P"
}
```

Common statuses are `400`, `401`, `403`, `404`, `409`, `412`, `422`, `429`, and `500`. Human-readable `detail` is not a stable programmatic contract; clients should branch on `status` and `code`.

The initial default limit is 600 authenticated API calls per API Client per minute. Token requests are limited to 30 attempts per Client ID and source address per minute. Eos may apply tighter operation-specific safety limits later. Every counted response includes `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset`; a `429` also includes `Retry-After`.

## Versioning and compatibility

- `/v1` is the compatibility boundary.
- Adding optional fields, enum values, endpoints, and webhook types is non-breaking.
- Removing or changing required fields, semantics, or authorization is breaking.
- Breaking changes require a new major API version.
- Deprecated operations receive published migration guidance and a sunset date.
- Each response may include additive fields before documentation consumers update.

## Audit identity

Every mutation records the API Client as actor:

```json
{
  "actor": {
    "type": "api_client",
    "id": "apic_01J8Q4W9N0TS9AF1CXY6J5KX2F",
    "name": "Salesforce project synchronizer"
  },
  "subject_member_id": "alice@example.com",
  "source": "eos_api_v1",
  "request_id": "req_01J8Q5A0MRV6Q7T1YVZ45JDF3P"
}
```

The member subject is omitted when none applies.

## OpenAPI and LLM use

The eventual OpenAPI document must describe exactly the operations in this linked set. It will use stable `operationId` values, complete examples, OAuth security declarations, error schemas, and Eos extensions for required Roles, supported principal types, side effects, and idempotency.

For coding LLMs:

- Use the Markdown link at the top of each page for clean context.
- Provide only the relevant domain page plus this overview when possible.
- Do not ask a model to infer undocumented fields or internal endpoints.
- Validate generated integrations against the Eos sandbox before production use.

Continue with [Authentication and API Clients](authentication.html).
