Skip to main content
API reference sections

HTTP API reference

Profiles

Profiles and their accounts, removal and restore, appearance, personal attributes, dictionary, reminders and workspace usage.

48 operations. The contract has no example values, so example bodies are generated from each schema: every field is shown with a placeholder of its type.

Every profile

GET/v1/profiles

an array of profiles

Authorization
Bearer token with read_documents

Responses

StatusDescriptionBody
200See above.array of Profile
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
[
  {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "purpose": "string",
    "avatar": "string",
    "icon": "string",
    "color": "string",
    "account": "string",
    "locale": {},
    "created_at": 0,
    "kind": "normal"
  }
]
Example request
curl "http://127.0.0.1:$PORT/v1/profiles" \
  -H "Authorization: Bearer $KORU_TOKEN"

Create a profile. Requires no account and no network.

POST/v1/profiles

the profile, with its new id

Authorization
Bearer token with manage_workspaces

Request body (required)

application/json NewProfile

FieldTypeDescription
namerequiredstring
localestring or null

BCP 47. Absent means undetermined - not English: the absence of an answer is not an answer.

It is the person's locale, not the language a client happens to be drawing in: a client with no Korean strings showing English to a ko-KR person still sends ko-KR, or the profile records something untrue and stays wrong on the day Korean arrives.

Default null

purposestring or null

Free text - "work", "school". Deliberately not an enum: it is theirs.

Default null

avatarstring or null

A token, <kind>:<value> - color:purple today, blob:<hash> when a person can upload a picture. Passed through unread.

Default null

iconstring or null

Default null

colorstring or null

Default null

Example request body
{
  "name": "string",
  "locale": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string"
}

Responses

StatusDescriptionBody
200See above.Profile
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string",
  "account": "string",
  "locale": {},
  "created_at": 0,
  "kind": "normal"
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "locale": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string"
}'

Create a Profile and its first workspace atomically; retry with the same Profile id

POST/v1/profiles/with-workspace

profile and workspace; ProfileExists on conflicting or retired identity

Authorization
Bearer token with manage_workspaces

Request body (required)

application/json CreateProfileWithWorkspace

FieldTypeDescription
idrequiredProfileId
namerequiredstring
localestring or null

Default null

purposestring or null

Default null

avatarstring or null

Default null

iconstring or null

Default null

colorstring or null

Default null

workspacerequiredFirstWorkspace
Example request body
{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "locale": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string",
  "workspace": {
    "name": "string",
    "icon": "string",
    "color": "string"
  }
}

Responses

StatusDescriptionBody
200See above.CreatedProfile
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "profile": {
    "id": "00000000-0000-4000-8000-000000000000",
    "name": "string",
    "purpose": "string",
    "avatar": "string",
    "icon": "string",
    "color": "string",
    "account": "string",
    "locale": {},
    "created_at": 0,
    "kind": "normal"
  },
  "workspace": {
    "id": "00000000-0000-4000-8000-000000000000",
    "owner": {},
    "name": "string",
    "created_at": 0,
    "last_opened_at": 0,
    "icon": "string",
    "color": "string",
    "pinned": false,
    "archived": false,
    "deleted_at": 0,
    "position": 0
  }
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/with-workspace" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "locale": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string",
  "workspace": {
    "name": "string",
    "icon": "string",
    "color": "string"
  }
}'

Resolve verified live content or prepare a workspace after confirming none is available

POST/v1/profiles/{owner}/workspaces/ensure-live

active, created, pending, listing_pending, uncertain, or removing

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
ownerrequiredpathstring

Request body (required)

application/json EnsureLiveWorkspace

FieldTypeDescription
namerequiredstring
Example request body
{
  "name": "string"
}

Responses

StatusDescriptionBody
200See above.EnsuredWorkspace
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "workspace": {
    "id": "00000000-0000-4000-8000-000000000000",
    "owner": {},
    "name": "string",
    "created_at": 0,
    "last_opened_at": 0,
    "icon": "string",
    "color": "string",
    "pinned": false,
    "archived": false,
    "deleted_at": 0,
    "position": 0
  },
  "issues": [
    {
      "workspace": "00000000-0000-4000-8000-000000000000",
      "cause": "string",
      "recovery": {
        "problem": "string",
        "from_checkpoint": 0,
        "quarantined": [
          "string"
        ],
        "skipped_updates": 0
      }
    }
  ],
  "state": "active"
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$OWNER/workspaces/ensure-live" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

Inspect committed workspace lifecycle without creating, migrating or repairing storage

GET/v1/profiles/{owner}/workspaces/authority

retained rows with read or unreadable authority and listing differences

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
ownerrequiredpathstring

Responses

StatusDescriptionBody
200See above.array of WorkspaceAuthority
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
[
  {
    "workspace": {
      "id": "00000000-0000-4000-8000-000000000000",
      "owner": {},
      "name": "string",
      "created_at": 0,
      "last_opened_at": 0,
      "icon": "string",
      "color": "string",
      "pinned": false,
      "archived": false,
      "deleted_at": 0,
      "position": 0
    },
    "authority": {
      "archived": false,
      "deleted_at": 0,
      "pinned": false,
      "applied": false,
      "state": "read"
    },
    "listing_differs": false
  }
]
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$OWNER/workspaces/authority" \
  -H "Authorization: Bearer $KORU_TOKEN"

Atomically bind a Profile to an exact hosted Koru Identity

PUT/v1/profiles/{id}/account

bound or already_bound; a compare-and-set mismatch never overwrites

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json BindProfileAccount

FieldTypeDescription
expected_identity_idstring or null
new_identity_idrequiredstring
Example request body
{
  "expected_identity_id": "string",
  "new_identity_id": "string"
}

Responses

StatusDescriptionBody
200See above.ProfileAccountBindingOutcome
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
"bound"
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/account" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "expected_identity_id": "string",
  "new_identity_id": "string"
}'

Atomically detach a hosted-deleted Profile for offline-only use

DELETE/v1/profiles/{id}/account

cleared or already_offline; local Profile content is retained

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json ClearProfileAccount

FieldTypeDescription
expected_identity_idrequiredstring
Example request body
{
  "expected_identity_id": "string"
}

Responses

StatusDescriptionBody
200See above.ProfileAccountClearOutcome
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
"cleared"
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/account" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "expected_identity_id": "string"
}'

Restore a locally removed Profile from retained Store data

PUT/v1/profiles/{id}/local

restored or already_active; workspace tombstones remain unchanged

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.LocalProfileRestoration
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
"restored"
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/local" \
  -H "Authorization: Bearer $KORU_TOKEN"

Mark an empty profile removed in this installation's Store catalog

DELETE/v1/profiles/{id}/local

removed after exact attempt check; profile and deleted workspace data remain

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json CompleteProfileRemoval

FieldTypeDescription
attemptRemovalAttemptId or null

Default null

Example request body
{
  "attempt": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.LocalProfileRemoval
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
"removed"
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/local" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "attempt": "00000000-0000-4000-8000-000000000000"
}'

Read the current Profile removal attempt without changing it

GET/v1/profiles/{id}/removal

persisted removal mark or null

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.RemovalMark or null
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "attempt": "00000000-0000-4000-8000-000000000000",
  "kind": "local",
  "started_at": 0,
  "last_step_at": 0,
  "stopped": false
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/removal" \
  -H "Authorization: Bearer $KORU_TOKEN"

Begin or supersede a stopped or expired Profile removal attempt

POST/v1/profiles/{id}/removal

fresh removal mark; a live attempt refuses competition

Authorization
Bearer token with destroy_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json BeginProfileRemoval

FieldTypeDescription
kindrequiredRemovalKind

Which device-local removal is running. Both kinds end in the local removed_at marker and leave every other device untouched; neither is the shared deletion (Store::delete_profile), which writes a root deletion fact instead of an attempt.

Example request body
{
  "kind": "local"
}

Responses

StatusDescriptionBody
200See above.RemovalMark
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "attempt": "00000000-0000-4000-8000-000000000000",
  "kind": "local",
  "started_at": 0,
  "last_step_at": 0,
  "stopped": false
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/removal" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "kind": "local"
}'

Keep a Profile by abandoning its exact local removal attempt

DELETE/v1/profiles/{id}/removal

null; hosted cleanup and superseded attempts are refused

Authorization
Bearer token with destroy_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json ProfileRemovalAttempt

FieldTypeDescription
attemptrequiredRemovalAttemptId

RemovalAttemptId - a client-minted v4 UUID, hyphenated and lowercase. Immutable, and never derived from a name or a path.

Example request body
{
  "attempt": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/removal" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "attempt": "00000000-0000-4000-8000-000000000000"
}'

Stop only the named current Profile removal attempt

POST/v1/profiles/{id}/removal/stop

null; a superseded attempt is refused

Authorization
Bearer token with destroy_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json ProfileRemovalAttempt

FieldTypeDescription
attemptrequiredRemovalAttemptId

RemovalAttemptId - a client-minted v4 UUID, hyphenated and lowercase. Immutable, and never derived from a name or a path.

Example request body
{
  "attempt": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/removal/stop" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "attempt": "00000000-0000-4000-8000-000000000000"
}'

List the restorable shared Profile deletions this device holds

GET/v1/profiles/deleted

one entry per active, unpurged Profile deletion batch with its captured targets, the retained Profile's name, and which targets are past retention or purged

Authorization
Bearer token with manage_workspaces

Responses

StatusDescriptionBody
200See above.array of DeletedProfileListing
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
[
  {
    "name": "string",
    "profile": "00000000-0000-4000-8000-000000000000",
    "deletion": "00000000-0000-4000-8000-000000000000",
    "batch_id": "00000000-0000-4000-8000-000000000000",
    "at_ms": 0,
    "retention_ms": 0,
    "targets": [
      "00000000-0000-4000-8000-000000000000"
    ],
    "expired_or_purged": [
      "00000000-0000-4000-8000-000000000000"
    ]
  }
]
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/deleted" \
  -H "Authorization: Bearer $KORU_TOKEN"

What deleting a Profile would move to Trash right now

GET/v1/profiles/{id}/deletion-preview

the live workspaces placed under the Profile and a placement revision the delete echoes back; a changed list refuses the stale confirmation

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.ProfileDeletionPreview
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "targets": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "placement_revision": 0
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/deletion-preview" \
  -H "Authorization: Bearer $KORU_TOKEN"

Delete a Profile as a shared batch: the Profile and every captured workspace move to Trash in one transaction

POST/v1/profiles/{id}/delete

the batch id and each target's deletion id; HTTP 409 idempotency_conflict when the preview is stale. Takes destroy_workspaces, like the workspace delete; the targets' rooms are disconnected first

Authorization
Bearer token with destroy_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json DeleteProfile

FieldTypeDescription
previewrequiredProfileDeletionPreview

What a Profile deletion would trash right now, with a revision the caller echoes back so a confirmation taken over a stale list is refused.

Example request body
{
  "preview": {
    "targets": [
      "00000000-0000-4000-8000-000000000000"
    ],
    "placement_revision": 0
  }
}

Responses

StatusDescriptionBody
200See above.ProfileDeletionBatch
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "batch_id": "00000000-0000-4000-8000-000000000000",
  "profile_deletion": "00000000-0000-4000-8000-000000000000",
  "targets": [
    [
      {}
    ]
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/delete" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "preview": {
    "targets": [
      "00000000-0000-4000-8000-000000000000"
    ],
    "placement_revision": 0
  }
}'

Restore a Profile deletion batch: the Profile and the workspaces trashed by exactly that deletion

POST/v1/profiles/{id}/restore

which targets came back, stayed in Trash under an independent deletion, were moved elsewhere already, or were purged. The same scope the delete takes

Authorization
Bearer token with destroy_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json RestoreProfile

FieldTypeDescription
deletionrequiredDeletionId

DeletionId - a client-minted v4 UUID, hyphenated and lowercase. Immutable, and never derived from a name or a path.

Example request body
{
  "deletion": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.ProfileRestoreOutcome
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "restored": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "left_in_trash": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "moved_elsewhere": [
    "00000000-0000-4000-8000-000000000000"
  ],
  "purged": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/restore" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "deletion": "00000000-0000-4000-8000-000000000000"
}'

One profile

GET/v1/profiles/{id}

a profile

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.Profile
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string",
  "account": "string",
  "locale": {},
  "created_at": 0,
  "kind": "normal"
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID" \
  -H "Authorization: Bearer $KORU_TOKEN"

Rename a profile in its replicated manifest

PATCH/v1/profiles/{id}

the profile, renamed

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json RenameProfile

FieldTypeDescription
namerequiredstring
Example request body
{
  "name": "string"
}

Responses

StatusDescriptionBody
200See above.Profile
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string",
  "account": "string",
  "locale": {},
  "created_at": 0,
  "kind": "normal"
}
Example request
curl -X PATCH "http://127.0.0.1:$PORT/v1/profiles/$ID" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'

Set a profile's switcher icon and named colour

PATCH/v1/profiles/{id}/appearance

the profile with both appearance fields

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json ProfileAppearance

FieldTypeDescription
iconstring or null

Default null

colorstring or null

Default null

Example request body
{
  "icon": "string",
  "color": "string"
}

Responses

StatusDescriptionBody
200See above.Profile
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "id": "00000000-0000-4000-8000-000000000000",
  "name": "string",
  "purpose": "string",
  "avatar": "string",
  "icon": "string",
  "color": "string",
  "account": "string",
  "locale": {},
  "created_at": 0,
  "kind": "normal"
}
Example request
curl -X PATCH "http://127.0.0.1:$PORT/v1/profiles/$ID/appearance" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "icon": "string",
  "color": "string"
}'

One profile's personal attributes for one entity, named by ?entity=<kind>:<workspace>:<document>:<node>

GET/v1/profiles/{id}/personal-attributes

the entity reference and its attributes for this profile only. An unset attribute is an absent key, never a null. The reference travels as a query parameter because it holds only ids

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring
entityrequiredquerystring

Canonical <kind>:<workspace>:<document>:<node> entity reference

Responses

StatusDescriptionBody
200See above.PersonalAttributesResponse
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "entity": "string",
  "attributes": {
    "key": {
      "text": "string",
      "type": "text"
    }
  }
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/personal-attributes?entity=$ENTITY" \
  -H "Authorization: Bearer $KORU_TOKEN"

Set one personal attribute on one entity, or clear it with a null value

PUT/v1/profiles/{id}/personal-attributes

the entity's attributes for this profile after the write. Personal state belongs to the profile in the path and never overwrites another profile's answer to the same question

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json SetPersonalAttribute

FieldTypeDescription
entityrequiredstring
keyrequiredstring
valuePersonalAttributeValue or null

Default null

Example request body
{
  "entity": "string",
  "key": "string",
  "value": {
    "text": "string",
    "type": "text"
  }
}

Responses

StatusDescriptionBody
200See above.PersonalAttributesResponse
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "entity": "string",
  "attributes": {
    "key": {
      "text": "string",
      "type": "text"
    }
  }
}
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/personal-attributes" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "entity": "string",
  "key": "string",
  "value": {
    "text": "string",
    "type": "text"
  }
}'

Every reminder for ?entity=<canonical entity reference>

GET/v1/profiles/{id}/reminders

the entity's synchronized reminder rules and action history

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring
entityrequiredquerystring

Canonical <kind>:<workspace>:<document>:<node> entity reference

Responses

StatusDescriptionBody
200See above.array of StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
Example 200 response
[
  {
    "rule": {
      "id": "00000000-0000-4000-8000-000000000000",
      "target": "string",
      "revision": "00000000-0000-4000-8000-000000000000",
      "status": "enabled",
      "schedule": {
        "wall": "string",
        "type": "floating"
      },
      "tone_override": "system"
    },
    "deleted": false,
    "actions": [
      {
        "id": "00000000-0000-4000-8000-000000000000",
        "occurrence": "string",
        "kind": {
          "instant_ms": 0,
          "type": "snoozed_until"
        }
      }
    ]
  }
]
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders?entity=$ENTITY" \
  -H "Authorization: Bearer $KORU_TOKEN"

Create a reminder at a client-minted id

POST/v1/profiles/{id}/reminders

the authoritative stored reminder; an identical retry is idempotent

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json RuleRequest

FieldTypeDescription
rulerequiredReminderRule
Example request body
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  }
}'

Fetch one reminder

GET/v1/profiles/{id}/reminders/{reminder}

the synchronized rule, deletion fact and scoped actions

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER" \
  -H "Authorization: Bearer $KORU_TOKEN"

Replace one whole reminder rule revision

PUT/v1/profiles/{id}/reminders/{reminder}

the authoritative stored reminder; path and body ids must match

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json RuleRequest

FieldTypeDescription
rulerequiredReminderRule
Example request body
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  }
}'

Monotonically delete one reminder

DELETE/v1/profiles/{id}/reminders/{reminder}

the reminder with its irreversible deletion fact set

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER" \
  -H "Authorization: Bearer $KORU_TOKEN"

Fetch one reminder

GET/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}

the synchronized rule, deletion fact and scoped actions

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER" \
  -H "Authorization: Bearer $KORU_TOKEN"

Replace one whole reminder rule revision

PUT/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}

the authoritative stored reminder; path and body ids must match

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json RuleRequest

FieldTypeDescription
rulerequiredReminderRule
Example request body
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  }
}'

Monotonically delete one reminder

DELETE/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}

the reminder with its irreversible deletion fact set

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER" \
  -H "Authorization: Bearer $KORU_TOKEN"

Pause one reminder as a new atomic revision

POST/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}/pause

the authoritative paused reminder

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json RevisionRequest

FieldTypeDescription
revisionrequiredRuleRevisionId
Example request body
{
  "revision": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER/pause" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "revision": "00000000-0000-4000-8000-000000000000"
}'

Resume one reminder as a new atomic revision

POST/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}/resume

the authoritative enabled reminder

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json RevisionRequest

FieldTypeDescription
revisionrequiredRuleRevisionId
Example request body
{
  "revision": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER/resume" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "revision": "00000000-0000-4000-8000-000000000000"
}'

Append a snooze action

POST/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}/snooze

the authoritative reminder; the body action must be snoozed_until

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json ActionRequest

FieldTypeDescription
actionrequiredOccurrenceAction
Example request body
{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER/snooze" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}'

Append a handled action

POST/v1/profiles/{id}/workspaces/{workspace}/reminders/{reminder}/handle

the authoritative reminder; the body action must be handled

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
workspacerequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json ActionRequest

FieldTypeDescription
actionrequiredOccurrenceAction
Example request body
{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/workspaces/$WORKSPACE/reminders/$REMINDER/handle" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}'

One profile's personal spelling dictionary, language tag to words

GET/v1/profiles/{id}/dictionary

every language's words for this profile only. An empty dictionary is an empty map, and it replicates between this person's devices and nobody else's

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.PersonalDictionaryResponse
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "words": {
    "key": [
      "string"
    ]
  }
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/dictionary" \
  -H "Authorization: Bearer $KORU_TOKEN"

Add or remove one personal-dictionary word for one language

PUT/v1/profiles/{id}/dictionary

the whole dictionary after the write. A removed word is a deleted key, never a stored false

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json SetDictionaryWord

FieldTypeDescription
languagerequiredstring
wordrequiredstring
presentrequiredboolean
Example request body
{
  "language": "string",
  "word": "string",
  "present": false
}

Responses

StatusDescriptionBody
200See above.PersonalDictionaryResponse
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "words": {
    "key": [
      "string"
    ]
  }
}
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/dictionary" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "language": "string",
  "word": "string",
  "present": false
}'

Clear one profile's personal spelling dictionary

DELETE/v1/profiles/{id}/dictionary

the empty dictionary after every word visible to this device is deleted

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.PersonalDictionaryResponse
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
{
  "words": {
    "key": [
      "string"
    ]
  }
}
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/dictionary" \
  -H "Authorization: Bearer $KORU_TOKEN"

Pause one reminder as a new atomic revision

POST/v1/profiles/{id}/reminders/{reminder}/pause

the authoritative paused reminder

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json RevisionRequest

FieldTypeDescription
revisionrequiredRuleRevisionId
Example request body
{
  "revision": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER/pause" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "revision": "00000000-0000-4000-8000-000000000000"
}'

Resume one reminder as a new atomic revision

POST/v1/profiles/{id}/reminders/{reminder}/resume

the authoritative enabled reminder

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json RevisionRequest

FieldTypeDescription
revisionrequiredRuleRevisionId
Example request body
{
  "revision": "00000000-0000-4000-8000-000000000000"
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER/resume" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "revision": "00000000-0000-4000-8000-000000000000"
}'

Append a snooze action

POST/v1/profiles/{id}/reminders/{reminder}/snooze

the authoritative reminder; the body action must be snoozed_until

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json ActionRequest

FieldTypeDescription
actionrequiredOccurrenceAction
Example request body
{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER/snooze" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}'

Append a handled action

POST/v1/profiles/{id}/reminders/{reminder}/handle

the authoritative reminder; the body action must be handled

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
reminderrequiredpathstring

Request body (required)

application/json ActionRequest

FieldTypeDescription
actionrequiredOccurrenceAction
Example request body
{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}

Responses

StatusDescriptionBody
200See above.StoredReminder
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
409

idempotency_conflict or profile_unit_required

Failure
Example 200 response
{
  "rule": {
    "id": "00000000-0000-4000-8000-000000000000",
    "target": "string",
    "revision": "00000000-0000-4000-8000-000000000000",
    "status": "enabled",
    "schedule": {
      "wall": "string",
      "type": "floating"
    },
    "tone_override": "system"
  },
  "deleted": false,
  "actions": [
    {
      "id": "00000000-0000-4000-8000-000000000000",
      "occurrence": "string",
      "kind": {
        "instant_ms": 0,
        "type": "snoozed_until"
      }
    }
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/$REMINDER/handle" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "action": {
    "id": "00000000-0000-4000-8000-000000000000",
    "occurrence": "string",
    "kind": {
      "instant_ms": 0,
      "type": "snoozed_until"
    }
  }
}'

Clear handled reminder history, optionally for one entity

DELETE/v1/profiles/{id}/reminder-history

the number of handled action ids monotonically hidden in the requested scope; active and snoozed actions remain

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring
entityquerystring

Optional canonical entity reference; omission clears the profile

Responses

StatusDescriptionBody
200See above.ClearedHistory
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
Example 200 response
{
  "cleared": 0
}
Example request
curl -X DELETE "http://127.0.0.1:$PORT/v1/profiles/$ID/reminder-history" \
  -H "Authorization: Bearer $KORU_TOKEN"

Fetch reminder settings

GET/v1/profiles/{id}/reminder-settings

end-of-day time and default tone

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.ReminderSettings
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
503

profile_private_unavailable

Failure
Example 200 response
{
  "end_of_day": "string",
  "default_tone": "system",
  "week_start": "system"
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/reminder-settings" \
  -H "Authorization: Bearer $KORU_TOKEN"

Update reminder settings independently

PATCH/v1/profiles/{id}/reminder-settings

the authoritative settings; absent fields are unchanged and null clears end-of-day

Authorization
Bearer token with edit_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json SettingsPatch

FieldTypeDescription
end_of_dayLocalTime or null
default_toneToneId or null
week_startWeekStartPreference or null
Example request body
{
  "end_of_day": "string",
  "default_tone": "system",
  "week_start": "system"
}

Responses

StatusDescriptionBody
200See above.ReminderSettings
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
503

profile_private_unavailable

Failure
Example 200 response
{
  "end_of_day": "string",
  "default_tone": "system",
  "week_start": "system"
}
Example request
curl -X PATCH "http://127.0.0.1:$PORT/v1/profiles/$ID/reminder-settings" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "end_of_day": "string",
  "default_tone": "system",
  "week_start": "system"
}'

Query active, waiting, missed, upcoming, or handled reminders

POST/v1/profiles/{id}/reminders/query

canonical joined rows; missed/upcoming require explicit caller now and canonical IANA zone

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json ReminderQuery

FieldTypeDescription
viewrequiredReminderView
now_msinteger (int64) or null
device_zonestring or null
Example request body
{
  "view": "active",
  "now_ms": 0,
  "device_zone": "string"
}

Responses

StatusDescriptionBody
200See above.ReminderQueryResponse
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
503

projection_unavailable, reminder_index_updating or profile_private_unavailable

Failure
Example 200 response
{
  "reminders": [
    {
      "stored": {
        "rule": {
          "id": "00000000-0000-4000-8000-000000000000",
          "target": "string",
          "revision": "00000000-0000-4000-8000-000000000000",
          "status": "enabled",
          "schedule": {
            "wall": "string",
            "type": "floating"
          },
          "tone_override": "system"
        },
        "deleted": false,
        "actions": [
          {
            "id": "00000000-0000-4000-8000-000000000000",
            "occurrence": "string",
            "kind": {
              "instant_ms": 0,
              "type": "snoozed_until"
            }
          }
        ]
      },
      "target": {
        "target": "string",
        "title": "string",
        "source_location": "string",
        "state": "active",
        "due": {
          "date": "string",
          "type": "date"
        },
        "projected": false
      },
      "occurrence_source": {
        "moment": {
          "wall": "string",
          "type": "floating"
        },
        "type": "one_time"
      },
      "reduced": {
        "effective": {
          "state": "deleted"
        },
        "handled_history": [
          "string"
        ]
      }
    }
  ],
  "updating_workspaces": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
Example request
curl -X POST "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/query" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "view": "active",
  "now_ms": 0,
  "device_zone": "string"
}'

Fetch the Agent's batched reminder reconciliation snapshot

GET/v1/profiles/{id}/reminders/reconciliation

device-neutral canonical rows joined to target existence, title, due, and bin state

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.ReminderSnapshot
400

invalid_request or invalid_id

Failure
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
404

profile_not_found or reminder_not_found

Failure
503

projection_unavailable, reminder_index_updating or profile_private_unavailable

Failure
Example 200 response
{
  "reminders": [
    {
      "stored": {
        "rule": {
          "id": "00000000-0000-4000-8000-000000000000",
          "target": "string",
          "revision": "00000000-0000-4000-8000-000000000000",
          "status": "enabled",
          "schedule": {
            "wall": "string",
            "type": "floating"
          },
          "tone_override": "system"
        },
        "deleted": false,
        "actions": [
          {
            "id": "00000000-0000-4000-8000-000000000000",
            "occurrence": "string",
            "kind": {
              "instant_ms": 0,
              "type": "snoozed_until"
            }
          }
        ]
      },
      "target": {
        "target": "string",
        "title": "string",
        "source_location": "string",
        "state": "active",
        "due": {
          "date": "string",
          "type": "date"
        },
        "projected": false
      },
      "occurrence_source": {
        "moment": {
          "wall": "string",
          "type": "floating"
        },
        "type": "one_time"
      },
      "reduced": {
        "effective": {
          "state": "deleted"
        },
        "handled_history": [
          "string"
        ]
      }
    }
  ],
  "settings": {
    "end_of_day": "string",
    "default_tone": "system",
    "week_start": "system"
  },
  "updating_workspaces": [
    "00000000-0000-4000-8000-000000000000"
  ]
}
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/reminders/reconciliation" \
  -H "Authorization: Bearer $KORU_TOKEN"

Live entry counts by kind and referenced blob bytes for every workspace in one profile

GET/v1/profiles/{id}/workspace-usage

one usage row per workspace, including deduplicated live file/blob bytes

Authorization
Bearer token with read_documents

Parameters

NameInTypeDescription
idrequiredpathstring

Responses

StatusDescriptionBody
200See above.array of WorkspaceUsage
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
[
  {
    "workspace": "00000000-0000-4000-8000-000000000000",
    "entries": 0,
    "kinds": {
      "key": 0
    },
    "stored_bytes": 0
  }
]
Example request
curl "http://127.0.0.1:$PORT/v1/profiles/$ID/workspace-usage" \
  -H "Authorization: Bearer $KORU_TOKEN"

Replace a profile's complete workspace order atomically

PUT/v1/profiles/{id}/workspace-order

that profile's workspaces in their saved order

Authorization
Bearer token with manage_workspaces

Parameters

NameInTypeDescription
idrequiredpathstring

Request body (required)

application/json WorkspaceOrder

FieldTypeDescription
workspacesrequiredarray of WorkspaceId

The complete ordered set, including archived and softly deleted rows.

Example request body
{
  "workspaces": [
    "00000000-0000-4000-8000-000000000000"
  ]
}

Responses

StatusDescriptionBody
200See above.array of Workspace
401

no bearer token, or one that is not recognised

Failure
403

the credential does not hold the required scope

Failure
Example 200 response
[
  {
    "id": "00000000-0000-4000-8000-000000000000",
    "owner": {},
    "name": "string",
    "created_at": 0,
    "last_opened_at": 0,
    "icon": "string",
    "color": "string",
    "pinned": false,
    "archived": false,
    "deleted_at": 0,
    "position": 0
  }
]
Example request
curl -X PUT "http://127.0.0.1:$PORT/v1/profiles/$ID/workspace-order" \
  -H "Authorization: Bearer $KORU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "workspaces": [
    "00000000-0000-4000-8000-000000000000"
  ]
}'

Generated from contract version 1. Last updated .

Privacy choices

Choose which optional tools Koru may use on this site. Your choice is saved in a cookie in this browser for 12 months. Privacy policy

Privacy choices

Keep you signed in, protect forms and remember your language and this choice.

Always on

PostHog and Google Analytics 4 measure page views and actions such as downloads, using cookies or local storage.

PostHog records how pages are used, with form inputs masked and private pages excluded. Needs Analytics.

Ahrefs Web Analytics measures visits and where they come from, and Google Ads measures whether our ads led to a visit or download.