Harnesslayer Docs
Back to landing

Reference

API Overview

POST/v1/organization/createCreate a Harnesslayer organization.PATCH/v1/organization/{organization_id}Update an organization name or slug.POST/v1/app/createCreate a Harnesslayer app.GET/v1/app/{app_id}Return one app by display id or slug.GET/v1/app/listReturn paginated apps for the organization.PATCH/v1/app/{app_id}Update app slug or display name.DELETE/v1/app/{app_id}Delete an app and related records.POST/v1/version/createRegister the next app version from an uploaded bundle.POST/v1/version/uploadCreate signed upload URLs for a new app version bundle.POST/v1/version/upload/{upload_id}/completeComplete a version upload and register it as the app head version.POST/v1/version/syncSync the app head version to profile states.POST/v1/version/rollbackMove an app head version back to an existing version.GET/v1/version/download/{version_id}Return a signed URL for a version archive.GET/v1/version/{version_id}Return one app version.GET/v1/version/listReturn paginated versions for an app.POST/v1/access_group/createCreate an access group.GET/v1/access_group/{access_group_id}Return one access group.GET/v1/access_group/listReturn paginated access groups for an app.PATCH/v1/access_group/{access_group_id}Update an access group.DELETE/v1/access_group/{access_group_id}Delete an access group.POST/v1/channel/createCreate an API or iMessage channel.GET/v1/channel/{channel_id}Return one channel.GET/v1/channel/listReturn paginated channels for an app.PATCH/v1/channel/{channel_id}Update a channel.DELETE/v1/channel/{channel_id}Delete a channel.POST/v1/response/runRun an app response through a channel.GET/v1/response/poll/{instance_id}Poll stream events and status for a response instance.POST/v1/response/stopRequest interruption for a running response stream.POST/v1/session/createCreate a persistent session.GET/v1/session/{session_id}Return one session.GET/v1/session/listReturn paginated sessions for an app.DELETE/v1/session/{session_id}Delete a session.POST/v1/profile/createCreate a user profile for an app.GET/v1/profile/{profile_id}Return one profile by display id or identifier.GET/v1/profile/listReturn paginated profiles for an app.PATCH/v1/profile/{profile_id}Update a profile.DELETE/v1/profile/{profile_id}Delete a profile.POST/v1/webhook/createCreate an app webhook for a supported event.POST/v1/webhook/updateUpdate an existing webhook configuration.POST/v1/state/createRegister the next profile state from an uploaded bundle.POST/v1/state/uploadCreate signed upload URLs for a new profile state bundle.POST/v1/state/upload/{upload_id}/completeComplete a state upload and register it as the profile head state.POST/v1/state/snapshotRegister and materialize an uploaded state snapshot.POST/v1/state/rollbackMove a profile head state back to an existing state.POST/v1/state/download/{state_id}Return a signed URL for a state archive.GET/v1/state/{state_id}Return one state.GET/v1/state/listReturn paginated states for a profile.GET/v1/instance/{instance_id}Return one response run instance.GET/v1/instance/listReturn paginated instances for an app.GET/v1/sync/{sync_id}Return one version sync job.GET/v1/sync/listReturn paginated sync jobs for an app.GET/v1/conflict/{conflict_id}Return one sync conflict record.GET/v1/conflict/listReturn paginated conflict records for an app.GET/v1/history/{history_id}Return one history record.GET/v1/history/listReturn paginated history records for an app.

API Reference

Organizations

Organization endpoints create and update owner-managed organizations. They use authenticated owner context rather than an organization API key, so call them with a user API key.

POST/v1/organization/create

Create an organization

Creates a new organization, API key, and owner membership. Send returnIfExist to reuse an existing organization with the same slug.

FieldLocationRequiredDescription
namebodyyesOrganization display name.
slugbodyyesURL-safe organization slug.
returnIfExistbodynoReturn an existing organization for the same owner and slug when present.
PATCH/v1/organization/{organization_id}

Update an organization

Updates an organization name or slug. The path accepts either the organization display id or slug.

FieldLocationRequiredDescription
namebodynoUpdated organization display name.
slugbodynoUpdated URL-safe organization slug.

API Reference

Apps

App endpoints create and manage the runtime entry point for a Harnesslayer product. App ids accept either the display id or slug where supported.

POST/v1/app/create

Create an app

Creates a new app. The type must be claude or openclaw.

FieldLocationRequiredDescription
slugbodyyesURL-safe app slug.
typebodyyesRuntime type. Use claude or openclaw.
namebodynoDisplay name.
limitbodynoOptional default access group settings: amount, interval, name, message.
credentialsbodynoClaude runtime vault credentials list.
returnIfExistbodynoReturn an existing app for the same slug when present.
curl -X POST "https://api.harnesslayer.ai/v1/app/create" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "slug": "demo-app",
    "type": "claude",
    "name": "Demo App"
  }'
GET/v1/app/{app_id}

Get an app

Returns one app by display id or slug.

GET/v1/app/list

List apps

Returns paginated apps. The current implementation requires appId as a query parameter.

PATCH/v1/app/{app_id}

Update an app

Updates app metadata. Body fields are optional and include slug and name.

FieldLocationRequiredDescription
slugbodynoUpdated URL-safe app slug.
namebodynoUpdated app display name.
DELETE/v1/app/{app_id}

Delete an app

Marks the app for deletion and starts the deletion job.

API Reference

Versions

Version endpoints register uploaded app source bundles, inspect versions, download archives, and sync the app head version to profile states.

POST/v1/version/create

Create a version

Registers the next app version from an already uploaded bundle under versionId on the app repo main branch.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
versionIdbodyyesUploaded version id. Must identify an uploaded directory on the app repo main branch.
curl -X POST "https://api.harnesslayer.ai/v1/version/create" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "app-...",
    "versionId": "ver-..."
  }'
POST/v1/version/upload

Upload a version

Creates Driftstone-backed signed URLs for app version files on the app repo main branch. Upload each file to its matching URL, then complete the upload.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
versionIdbodynoVersion id to use as the storage directory. Generated when omitted.
filesbodyyesList of file objects with name and hash. Upload each file to the matching signed URL.
curl -X POST "https://api.harnesslayer.ai/v1/version/upload" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "app-...",
    "files": [
      { "name": "agent.json", "hash": "sha256-..." },
      { "name": "README.md", "hash": "sha256-..." }
    ]
  }'

# PUT each file to the matching data.uploadUrls[].url with Content-Type: application/octet-stream.
POST/v1/version/upload/{upload_id}/complete

Complete a version upload

Marks the underlying Driftstone upload complete and registers versionId as the app head version.

FieldLocationRequiredDescription
upload_idpathyesUpload id returned by /v1/version/upload.
appIdbodyyesApp display id.
versionIdbodyyesVersion id returned by /v1/version/upload.
curl -X POST "https://api.harnesslayer.ai/v1/version/upload/upload-.../complete" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "app-...",
    "versionId": "ver-..."
  }'
POST/v1/version/sync

Sync the app head version

Starts a background sync of the app head version to profile states and returns a syncId. Pass strategy as manual, current, incoming, or smart. Pass profileIds to sync only specific profiles.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
strategybodynoSync strategy. Use manual, current, incoming, or smart.
profileIdsbodynoOptional list of profile display IDs. When provided, only those profiles are synced.
curl -X POST "https://api.harnesslayer.ai/v1/version/sync" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "app-...",
    "strategy": "smart",
    "profileIds": ["prof-...", "prof-..."]
  }'
POST/v1/version/rollback

Rollback the app head version

Moves the app headVersionId to an existing version that already belongs to the app and records a rollback. This does not create or delete versions. Future submissions and syncs use the rolled-back app head.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
toVersionIdbodyyesExisting version id to make the app head version.
reasonbodynoOptional reason stored on the rollback record.
curl -X POST "https://api.harnesslayer.ai/v1/version/rollback" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "app-...",
    "toVersionId": "ver-...",
    "reason": "Rollback to the last stable version"
  }'
GET/v1/version/download/{version_id}

Download a version

Returns a short-lived signed URL in data.url for downloading the version archive.

GET/v1/version/{version_id}

Get a version

Returns one app version by id.

GET/v1/version/list

List versions

Returns paginated versions for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.

API Reference

Access Groups

Access groups are used for profile-level gating and limits. They support daily, monthly, and yearly reset policies.

POST/v1/access_group/create

Create an access group

Required body fields are appId, name, limit, and limitReset. Optional body includes limitMessage.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
namebodyyesDisplay name.
limitbodyyesPositive integer usage limit.
limitResetbodyyesReset policy: daily, monthly, or yearly.
limitMessagebodynoMessage shown when the limit is exceeded.
GET/v1/access_group/{access_group_id}

Get an access group

Returns one access group.

GET/v1/access_group/list

List access groups

Returns paginated access groups for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.
PATCH/v1/access_group/{access_group_id}

Update an access group

Partially updates name, limit, limitReset, or limitMessage.

FieldLocationRequiredDescription
namebodynoUpdated display name.
limitbodynoPositive integer usage limit.
limitResetbodynoReset policy: daily, monthly, or yearly.
limitMessagebodynoMessage shown when the limit is exceeded.
DELETE/v1/access_group/{access_group_id}

Delete an access group

Deletes an access group. App default groups cannot be deleted.

API Reference

Channels

Channel endpoints create API and iMessage entry points for an app. API channels omit data. iMessage channels require Sendblue credentials and a sender number.

POST/v1/channel/create

Create a channel

Creates a channel with type set to api or imessage.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
slugbodyyesURL-safe channel slug.
typebodyyesChannel type. Use api or imessage.
namebodynoDisplay name.
webhookbodyapi onlyOptional API channel webhook: name, url, optional headers.
databodyimessage onlyRequired iMessage data: sendBlueAPIKey, sendBlueSecretKey, fromNumber.
returnIfExistbodynoReturn existing channel with the same slug.
curl -X POST "https://api.harnesslayer.ai/v1/channel/create" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "demo-app",
    "slug": "my-api",
    "type": "api"
  }'
GET/v1/channel/{channel_id}

Get a channel

Returns one channel.

GET/v1/channel/list

List channels

Returns paginated channels for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.
PATCH/v1/channel/{channel_id}

Update a channel

Updates channel metadata. The current implementation applies name updates.

FieldLocationRequiredDescription
slugbodynoValidated but not currently applied by the handler.
namebodynoUpdated channel display name.
DELETE/v1/channel/{channel_id}

Delete a channel

Deletes a channel.

API Reference

Responses

Response endpoints run the agent through a channel and poll streaming events for the created instance.

POST/v1/response/run

Run a response

Use sessionId to preserve conversation continuity across turns. The endpoint returns an instanceId.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
channelIdbodyyesChannel display id.
userIdbodyyesExternal user identifier.
inputbodyconditionalInput message for the agent.
imagesbodyconditionalImages for Claude or OpenClaw apps.
sessionIdbodynoPreserves conversation continuity across turns.
curl -X POST "https://api.harnesslayer.ai/v1/response/run" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "demo-app",
    "channelId": "my-api",
    "userId": "user@example.com",
    "sessionId": "my-custom-session-id",
    "input": "Hello"
  }'
GET/v1/response/poll/{instance_id}

Poll response events

Returns stream events and status for the instance. timeoutMs defaults to 25000.

FieldLocationRequiredDescription
afterquerynoPoll events after this cursor. Defaults to 0.
timeoutMsquerynoLong-poll timeout. Defaults to 25000.
POST/v1/response/stop

Stop a response

Requests interruption for a running response stream by instanceId. Claude apps send an interrupt; OpenClaw apps abort the active gateway session run.

FieldLocationRequiredDescription
instanceIdbodyyesRunning response instance id.

API Reference

Sessions

Session endpoints create persistent sessions and retrieve, list, or delete session records. For Claude apps, type must be single.

POST/v1/session/create

Create a session

Required body fields are appId and type.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
typebodyyesSession type. Claude apps only support single.
GET/v1/session/{session_id}

Get a session

Returns one session.

GET/v1/session/list

List sessions

Returns paginated sessions for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.
DELETE/v1/session/{session_id}

Delete a session

Deletes a session.

API Reference

Profiles

Profile endpoints manage user profile records for an app and optionally assign those profiles to access groups.

POST/v1/profile/create

Create a profile

Creates a profile using an external identifier.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
identifierbodyyesExternal user or profile identifier.
accessGroupIdbodynoAccess group assigned to the profile.
metadatabodynoArbitrary JSON metadata stored on the profile.
returnIfExistbodynoReturn an existing profile with the same identifier.
GET/v1/profile/{profile_id}

Get a profile

Returns one profile by display id. With appId, the same path can retrieve by profile identifier.

FieldLocationRequiredDescription
profile_idpathyesProfile display id, or the profile identifier when appId is provided.
appIdquerynoApp display id. Required when profile_id is an identifier.
GET/v1/profile/list

List profiles

Returns paginated profiles for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.
PATCH/v1/profile/{profile_id}

Update a profile

Updates identifier, accessGroupId, or metadata.

FieldLocationRequiredDescription
identifierbodynoUpdated external user or profile identifier.
accessGroupIdbodynoUpdated access group assigned to the profile.
metadatabodynoMetadata object, or null to clear metadata.
DELETE/v1/profile/{profile_id}

Delete a profile

Marks the profile for deletion and starts the deletion job.

API Reference

Webhooks

Webhook endpoints register outbound calls for app events. The current event is profile.created. The configured method supports GET, POST, PUT, PATCH, DELETE; POST is the default.

POST/v1/webhook/create

Create a webhook

Creates a webhook for an app. New webhooks start with runCount set to 0; lastTriggeredAt is added after the first successful delivery.

FieldLocationRequiredDescription
appIdbodyyesApp display id.
eventbodyyesWebhook event. Currently supports profile.created.
methodbodynoHTTP method. Defaults to POST. Supports GET, POST, PUT, PATCH, and DELETE.
urlbodyyes for createDestination URL.
headersbodynoOptional string-to-string HTTP headers.
curl -X POST "https://api.harnesslayer.ai/v1/webhook/create" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "appId": "demo-app",
    "event": "profile.created",
    "method": "POST",
    "url": "https://example.com/harnesslayer/webhook",
    "headers": {
      "Authorization": "Bearer your-webhook-secret"
    }
  }'
POST/v1/webhook/update

Update a webhook

Updates the webhook destination, method, headers, event, or run metadata. Send nullable fields such as headers or lastTriggeredAt as null to clear them.

FieldLocationRequiredDescription
webhookIdbodyyesWebhook id to update.
idbodyaliasAlias for webhookId.
eventbodynoWebhook event. Currently supports profile.created.
methodbodynoHTTP method. Supports GET, POST, PUT, PATCH, and DELETE.
urlbodynoDestination URL.
headersbodynoOptional string-to-string HTTP headers.
lastTriggeredAtbodynoOptional ISO datetime. Send null on update to clear it.
runCountbodynoNon-negative integer.
curl -X POST "https://api.harnesslayer.ai/v1/webhook/update" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "webhookId": "wh-...",
    "method": "PATCH",
    "url": "https://example.com/harnesslayer/webhook"
  }'

API Reference

States

State endpoints register uploaded profile state bundles, materialize snapshots, inspect state records, and return signed download URLs.

POST/v1/state/create

Create a state

Registers the next profile state from an already uploaded bundle under stateId on the profile branch.

FieldLocationRequiredDescription
profileIdbodyyesProfile display id.
stateIdbodyyesUploaded state id. Must identify an uploaded directory on the profile branch.
POST/v1/state/upload

Upload a state

Creates Driftstone-backed signed URLs for profile state files on the profile branch. The profile branch is created when needed. Upload each file to its matching URL, then complete the upload.

FieldLocationRequiredDescription
profileIdbodyyesProfile display id.
stateIdbodynoState id to use as the storage directory. Generated when omitted.
filesbodyyesList of file objects with name and hash. Upload each file to the matching signed URL.
curl -X POST "https://api.harnesslayer.ai/v1/state/upload" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "prof-...",
    "files": [
      { "name": "agent.json", "hash": "sha256-..." },
      { "name": "memory.json", "hash": "sha256-..." }
    ]
  }'

# PUT each file to the matching data.uploadUrls[].url with Content-Type: application/octet-stream.
POST/v1/state/upload/{upload_id}/complete

Complete a state upload

Marks the underlying Driftstone upload complete and registers stateId as the profile head state.

FieldLocationRequiredDescription
upload_idpathyesUpload id returned by /v1/state/upload.
profileIdbodyyesProfile display id.
stateIdbodyyesState id returned by /v1/state/upload.
curl -X POST "https://api.harnesslayer.ai/v1/state/upload/upload-.../complete" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "prof-...",
    "stateId": "state-..."
  }'
POST/v1/state/snapshot

Create a state snapshot

Registers an uploaded state snapshot and materializes it asynchronously.

FieldLocationRequiredDescription
profileIdbodyyesProfile display id.
storageUrlbodyyesUploaded snapshot archive URL.
sandboxIdbodynoOptional sandbox id associated with the snapshot.
POST/v1/state/rollback

Rollback a profile head state

Moves the profile headStateId to an existing state that already belongs to the profile and records a rollback. This does not create or delete states. Future submissions for that profile use the rolled-back state.

FieldLocationRequiredDescription
profileIdbodyyesProfile display id.
toStateIdbodyyesExisting state id to make the profile head state.
reasonbodynoOptional reason stored on the rollback record.
curl -X POST "https://api.harnesslayer.ai/v1/state/rollback" \
  -H "Authorization: Bearer dk-..." \
  -H "Content-Type: application/json" \
  -d '{
    "profileId": "prof-...",
    "toStateId": "state-...",
    "reason": "Restore profile to a known good state"
  }'
POST/v1/state/download/{state_id}

Download a state

Returns a short-lived signed URL in data.url for downloading the state archive.

GET/v1/state/{state_id}

Get a state

Returns one state.

GET/v1/state/list

List states

Returns paginated states for a profile.

FieldLocationRequiredDescription
profileIdqueryyesProfile id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.

API Reference

Instances

Instance endpoints inspect response run instances and list execution records by app.

GET/v1/instance/{instance_id}

Get an instance

Returns one instance. Required path parameter: instance_id.

GET/v1/instance/list

List instances

Returns paginated instances for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.

API Reference

Sync

Sync endpoints inspect jobs created by version sync operations.

GET/v1/sync/{sync_id}

Get a sync job

Returns one sync job. Required path parameter: sync_id.

GET/v1/sync/list

List sync jobs

Returns paginated sync jobs for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.

API Reference

Conflicts

Conflict endpoints inspect records generated during app or profile sync.

GET/v1/conflict/{conflict_id}

Get a conflict

Returns one conflict. Required path parameter: conflict_id.

GET/v1/conflict/list

List conflicts

Returns paginated conflicts for an app.

FieldLocationRequiredDescription
appIdqueryyesApp display id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.

API Reference

History

History endpoints inspect history records and list execution history by app, profile, session, user, or history id.

GET/v1/history/{history_id}

Get a history record

Returns one history record. Required path parameter: history_id.

GET/v1/history/list

List history records

Returns paginated history records by filter.

FieldLocationRequiredDescription
appIdqueryconditionalApp display id. At least one filter is required.
profileIdqueryconditionalProfile id.
sessionIdqueryconditionalSession id.
userIdqueryconditionalExternal user identifier.
historyIdqueryconditionalHistory record id.
pagequerynoPage number. Defaults to 1.
pageSizequerynoPage size. Defaults to 10.

Recommended flow

Model app

Publish version

Open channel

Run session