API Overview
The Inherent Public API provides programmatic access to your workspace's knowledge base. Use it to upload documents, perform semantic search, and retrieve document content and chunks.
The API is organized around REST. It accepts JSON-encoded request bodies (for search) and multipart/form-data (for uploads), returns JSON-encoded responses, and uses standard HTTP status codes.
Base URLs
| Environment | Base URL |
|---|---|
| Production | https://api.inherent.systems |
| Development | https://dev-api.inherent.systems |
All versioned endpoints are prefixed with /api/v1/. Health check endpoints are at the root path.
https://api.inherent.systems/api/v1
API Versioning
The API is versioned via the URL path. The current version is v1.
Future versions will be introduced as /api/v2/, etc. Existing versions will continue to be supported with advance deprecation notice before removal.
Authentication
All API requests (except health checks) require authentication using an API key. Keys are prefixed with ink_ and can be created from the Inherent dashboard under Settings > API Keys.
Provide the key using either method:
| Method | Header | Example |
|---|---|---|
| API Key (preferred) | X-API-Key | X-API-Key: ink_live_abc123... |
| Bearer Token | Authorization | Authorization: Bearer ink_live_abc123... |
curl https://api.inherent.systems/api/v1/documents \
-H "X-API-Key: ink_live_abc123..."
If the key is missing or invalid, the API returns a 401 Unauthorized error.
API Key Permissions
Each API key is scoped with one or more permissions:
| Permission | Grants access to |
|---|---|
read | List documents, get document details, get chunks |
write | Upload documents |
search | Semantic search |
A request to an endpoint that requires a permission the key does not have returns 403 Forbidden.
Content Types
| Content Type | When to use |
|---|---|
application/json | Request and response bodies for all JSON endpoints |
multipart/form-data | Document uploads (POST /api/v1/documents) |
Error Format
All errors follow the RFC 7807 Problem Details standard:
{
"type": "https://api.inherent.systems/errors/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded the maximum of 100 requests per minute. Please retry after 23 seconds.",
"instance": "/api/v1/search",
"trace_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-04-03T12:34:56.789Z"
}
Error Fields
| Field | Type | Description |
|---|---|---|
type | string | A URI reference that identifies the error type |
title | string | A short, human-readable summary of the problem |
status | integer | The HTTP status code |
detail | string | A detailed, human-readable explanation specific to this occurrence |
instance | string | The request path that produced the error |
trace_id | string | A UUID for tracing the request through logs and support |
timestamp | string | ISO 8601 timestamp of when the error occurred |
Common HTTP Status Codes
| Status | Meaning |
|---|---|
200 | OK -- request succeeded |
201 | Created -- resource was created |
400 | Bad Request -- invalid or missing parameters |
401 | Unauthorized -- missing or invalid API key |
403 | Forbidden -- API key lacks the required permission |
404 | Not Found -- the requested resource does not exist |
413 | Payload Too Large -- uploaded file exceeds the 50 MB limit |
422 | Unprocessable Entity -- request body failed validation |
429 | Too Many Requests -- rate limit exceeded |
500 | Internal Server Error |
Rate Limiting
API requests are rate-limited per API key. The limits depend on your plan.
Every response includes rate limit headers:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed in the current window |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp (seconds) when the current window resets |
Retry-After | Seconds to wait before retrying (included only on 429 responses) |
Example response headers:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 297
X-RateLimit-Reset: 1743696000
When you exceed the rate limit, the API responds with HTTP 429:
{
"type": "https://api.inherent.systems/errors/rate-limit-exceeded",
"title": "Rate Limit Exceeded",
"status": 429,
"detail": "You have exceeded the maximum of 100 requests per minute. Please retry after 23 seconds.",
"instance": "/api/v1/search",
"trace_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-04-03T12:34:56.789Z"
}
Pagination
List endpoints support offset-based pagination via query parameters:
| Parameter | Type | Default | Constraints | Description |
|---|---|---|---|---|
page | integer | 1 | Minimum 1 | Page number |
page_size | integer | 20 | Minimum 1, maximum 100 | Number of items per page |
Paginated responses include metadata alongside the results:
{
"documents": [ ... ],
"total": 142,
"page": 2,
"page_size": 20
}
API Endpoints
Search
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/search | Semantic search across workspace documents |
Documents
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/documents | Upload a document for ingestion |
| GET | /api/v1/documents | List all documents |
| GET | /api/v1/documents/:document_id | Get a specific document |
Chunks
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/chunks/:document_id | Get all chunks for a document |
| GET | /api/v1/chunks/:document_id/context | Get full document context |
Health
| Method | Endpoint | Description |
|---|---|---|
| GET | /health | Liveness check (no auth) |
| GET | /health/ready | Readiness check (no auth) |
| GET | /health/live | Liveness alias (no auth) |