API Reference
Every request (except health checks) requires a Bearer token. All responses are JSON.
On this page
Authentication
How to create, use, and manage API tokens.
All API endpoints (except GET /api/v1/health) require a valid Bearer token. Tokens are created through Settings → API Tokens in the web UI.
Creating a token
- Navigate to Settings → API Tokens in the web UI.
- Enter a token name and choose a scope (
readorread_write). - Click Create to generate the token.
Token values are shown only once at creation time. Be sure to copy and store them securely.
Token format
Tokens are 128 hex-character strings with a ms_ prefix:
<example>: ms_3c5a7f9b1e4d8c0a6f2e3b9d8c7a6f5e4d3c2b1a09876543210abcdef123456
Token scopes
| Scope | Description |
|---|---|
“read” |
Read-only access. Accepts GET endpoints only. |
“read_write” |
Full access. Accepts all endpoints including POST, PUT, PATCH, and DELETE. |
Including the token in requests
Send the token in the Authorization header as a Bearer token:
Authorization: Bearer ms_3c5a7f9b1e4d8c0a6f2e3b9d8c7a6f5e4d3c2b1a09876543210abcdef123456
Memories
Create, read, update, and delete memories in your family.
GET
/api/v1/memories
read scope
List memories for the authenticated user’s family, with cursor-based pagination.
Parameters
| Param | Description |
|---|---|
cursor |
Pagination cursor from a previous next_cursor meta value. |
per_page |
Number of results per page (1–100, default 25). |
q |
Full-text search query across memory content. |
Response
{
"data": [
{ "id": "aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa",
"family_id": "bbbbbbbb-bbbb-4bbb-bbbb-bbbbbbbbbbbb",
"created_by_user_id": "cccccccc-cccc-4ccc-cccc-cccccccccccc",
"title": "...", "transcript": "...",
"notes": "...", "recorded_at": "2025-01-01T00:00:00Z",
"location_name": "...",
"tags": [], "visibility": "visible",
"transcription_status": "completed",
"transcription_completed_at": "2025-01-01T00:00:00Z",
"ai_data": null, "ai_extraction_status": null,
"ai_extraction_completed_at": null,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z",
"first_memory": false }
],
"meta": {
"next_cursor": "cmVjb3JkZWQtYXQtdXVpZD18MQ==",
"total_count": 42
}
}
GET
/api/v1/memories/:id
read scope
Return a single memory’s details.
Response
{
"data": {
"id": "aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaaaa",
"family_id": "bbbbbbbb-bbbb-4bbb-bbbb-bbbbbbbbbbbb",
"created_by_user_id": "cccccccc-cccc-4ccc-cccc-cccccccccccc",
"title": "...",
"transcript": "...",
"notes": "...",
"recorded_at": "2025-01-01T00:00:00Z",
"location_name": "...",
"tags": [],
"visibility": "visible",
"transcription_status": "completed",
"transcription_completed_at": "2025-01-01T00:00:00Z",
"ai_data": null,
"ai_extraction_status": null,
"ai_extraction_completed_at": null,
"created_at": "2025-01-01T00:00:00Z",
"updated_at": "2025-01-01T00:00:00Z",
"first_memory": false
}
}
POST
/api/v1/memories
write scope
Create a new memory. Returns 201 Created.
Accepted params
| Param | Description |
|---|---|
audio | Audio file blob (mutually exclusive with transcript). |
recorded_at | When the memory was recorded. |
duration_seconds | Audio duration in seconds. |
transcript_language | Language of the transcript. |
transcript | Text transcript (mutually exclusive with audio). |
title | Memory title. |
notes | Narrative notes. |
location_name | Location name. |
visibility | Visibility state. |
pinned | Pin the memory. |
tags[] | Array of tags. |
Response (201)
{
"data": {
"id": 1,
"family_id": 1,
"created_by_user_id": 1,
...
}
}
PUT
/api/v1/memories/:id
write scope
Update an existing memory. Returns 200 OK.
Accepted params
| Param | Description |
|---|---|
title | Memory title. |
notes | Narrative notes. |
recorded_at | When the memory was recorded. |
visibility | Visibility state. |
pinned | Pin the memory. |
tags[] | Array of tags. |
Response (200)
{
"data": {
"id": 1,
...
}
}
DELETE
/api/v1/memories/:id
write scope
Delete a memory. Audio attachments are purged.
Response
204 No Content
Tokens
Manage API tokens programmatically.
GET
/api/v1/tokens
read scope
List active (non-revoked) API tokens for the user's family.
Response
{
"data": [
{
"id": 1,
"name": "Mobile App",
"scope": "read_write",
"family_id": 1,
"last_used_at": "2025-01-01T00:00:00Z",
"created_at": "2025-01-01T00:00:00Z"
}
]
}
POST
/api/v1/tokens
write scope
Create a new API token. Returns 201 with a one-time token field.
Accepted params
| Param | Description |
|---|---|
token[name] | Token name (max 100 chars). |
token[scope] | Scope: read or read_write. |
Response (201)
{
"data": {
"id": 1,
"name": "Mobile App",
"scope": "read_write",
"family_id": 1,
"last_used_at": null,
"created_at": "2025-01-01T00:00:00Z",
"token": "ms_3c5a7f9b1e4d8c0a6f2e3b9d8c7a6f5e4d3c2b1a09876543210abcdef123456"
}
}
token is shown only once.
DELETE
/api/v1/tokens/:id
write scope
Revoke an active API token.
Response
204 No Content
POST
/api/v1/tokens/:id/rotate
write scope
Rotate a token. Returns the new raw token once.
Response
{
"data": {
"id": 1,
"name": "Mobile App",
"scope": "read_write",
"family_id": 1,
"last_used_at": null,
"created_at": "2025-01-01T00:00:00Z",
"token": "ms_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
}
}
Family
Manage family members and send invitations.
Family Summary
GET
/api/v1/family
read scope
Returns summary information for the authenticated user's family.
Response
{
"data": {
"id": "ffffffff-ffff-4fff-ffff-ffffffffffff",
"name": "The Smiths",
"plan_code": "premium",
"member_count": 4
}
}
Disposition of Fields
Authenticated API account-management fields—such as family_id,
created_by_user_id, membership and user IDs, member email, plan and member counts, and
processing state—support family management and integration within the authenticated account.
These fields are intentionally not portable export fields.
Portable exports independently use family_name, minimal member name/role/joined_at, and archival
memory and media fields. They retain memory and media object IDs where needed to cross-reference archived
metadata and files, while omitting account-management IDs, email addresses, and processing state.
GET
/api/v1/family/members
read scope
List all members of the authenticated user's family.
Response
{
"data": [
{
"id": "dddddddd-dddd-4ddd-dddd-dddddddddddd",
"user_id": "eeeeeeee-eeee-4eee-eeee-eeeeeeeeeeee",
"name": "Jane Doe",
"email": "jane@example.com",
"role": "owner",
"joined_at": "2025-01-01T00:00:00Z"
}
]
}
PATCH
/api/v1/family/members/:id
write scope + admin/owner
Update a family member's role. Requires admin or owner role.
Accepted params
| Param | Description |
|---|---|
role | New role: owner, admin, member, or viewer. |
Response (200)
{
"data": {
"id": "dddddddd-dddd-4ddd-dddd-dddddddddddd",
"user_id": "eeeeeeee-eeee-4eee-eeee-eeeeeeeeeeee",
"name": "Jane Doe",
"email": "jane@example.com",
"role": "admin",
"joined_at": "2025-01-01T00:00:00Z"
}
}
DELETE
/api/v1/family/members/:id
write scope + admin/owner
Remove a family member. Cannot remove yourself.
Response
204 No Content
POST
/api/v1/family/invitations
write scope
Send an invitation to join the family. An email is sent to the invitation address.
Accepted params
| Param | Description |
|---|---|
invitation[email] | Email address of the person to invite. |
invitation[role] | Role to assign: owner, admin, or member. |
Response (201)
{
"data": {
"id": 1,
"email": "invitee@example.com",
"role": "member",
"status": "pending"
}
}
Health
Check API availability without authentication.
Health
GET
/api/v1/health
No authentication required. Returns a JSON body confirming the API is operational.
Response
{
"status": "ok"
}
Error Responses
Standard error formats returned by all endpoints.
Error Responses
All API errors follow a consistent JSON structure with an error or errors object.
Single errors
Returned for authentication failures, forbidden access, and general errors.
{
"error": {
"code": "...",
"message": "..."
}
}
Validation errors
Returned when request body parameter validation fails. Fields are keyed by attribute.
{
"errors": {
"field": ["message"]
}
}