Skip to main content

External API & Programs

Use this page when you want a simple external program, script, local server, or backend service to control your current Chastify lock.

The easiest way is to create a user-wide DEV token, then send it as a bearer token to the /api/apps/v1/* endpoints.

Create A DEV Token

  1. Open Chastify.
  2. Go to Developer API.
  3. Find User-wide DEV API keys.
  4. Create a key.
  5. Copy the token immediately. It is only shown once.

Use it in requests like this:

curl https://chastify.net/api/apps/v1/session \
-H "Authorization: Bearer YOUR_DEV_TOKEN"

DEV tokens:

  • do not require creating an extension
  • do not expire automatically
  • work for your current active lock and future active lock sessions
  • use your role on the active lock, either wearer or keyholder
  • can be revoked from the Developer API page

Treat a DEV token like a password. Anyone with the token can call the Developer API as you.

First Call: Check The Current Lock

Start with:

GET https://chastify.net/api/apps/v1/session

Example:

curl https://chastify.net/api/apps/v1/session \
-H "Authorization: Bearer YOUR_DEV_TOKEN"

This returns your current lock context, role, scopes, remaining time, and lockData.

Lock Data Helpers

GET /api/apps/v1/session includes lockData, which is designed to be easy for programs and rule engines to read.

Common booleans:

  • frozen
  • unlockable
  • trusted
  • taskAssigned: true when the active lock has an open TaskRun

Common numbers:

  • timeLockedSeconds
  • timeRemainingSeconds
  • maxTimeRemainingSeconds
  • taskPoints

Common strings:

  • lockTitle
  • wearer profile fields
  • keyholder profile fields

Privacy note:

  • wearerLastSeenTimestamp and keyholderLastSeenTimestamp are null when that user has disabled online status.

Main Lock Action Endpoints

These endpoints are the ones most external programs use to modify a lock.

POST https://chastify.net/api/apps/v1/action
POST https://chastify.net/api/apps/v1/lock/apply-time
POST https://chastify.net/api/apps/v1/lock/freeze
POST https://chastify.net/api/apps/v1/lock/unfreeze
POST https://chastify.net/api/apps/v1/logs/custom

All requests use:

Authorization: Bearer YOUR_DEV_TOKEN
Content-Type: application/json

Add Or Remove Time

Use the simple time endpoint when you only want to change remaining time.

Add 10 minutes:

curl -X POST https://chastify.net/api/apps/v1/lock/apply-time \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"deltaSeconds":600}'

Remove 5 minutes:

curl -X POST https://chastify.net/api/apps/v1/lock/apply-time \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"deltaSeconds":-300}'

Freeze And Unfreeze

Freeze for 30 minutes:

curl -X POST https://chastify.net/api/apps/v1/lock/freeze \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"durationSeconds":1800}'

Unfreeze:

curl -X POST https://chastify.net/api/apps/v1/lock/unfreeze \
-H "Authorization: Bearer YOUR_DEV_TOKEN"

General Action Endpoint

Use:

POST https://chastify.net/api/apps/v1/action

Body shape:

{
"name": "add_time",
"params": 600
}

Example:

curl -X POST https://chastify.net/api/apps/v1/action \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"add_time","params":600}'

Supported Action Names

name supports:

  • add_time
  • remove_time
  • freeze
  • pillory
  • unfreeze
  • toggle_freeze
  • settings.patch
  • task.assign
  • task.start_timer
  • task.complete
  • hygienic_unlock.start
  • pillory.end

Action constraints:

  • Task actions require the Tasks module to be enabled on the lock.
  • hygienic_unlock.start requires Hygienic Opening to be enabled and no active hygiene session.
  • Device commands require a supported connected device and permissions.

Useful Action Examples

Remove 15 minutes:

{
"name": "remove_time",
"params": 900
}

Freeze for 5 minutes:

{
"name": "freeze",
"params": {
"durationSeconds": 300
}
}

Toggle freeze:

{
"name": "toggle_freeze",
"params": {
"durationSeconds": 300
}
}

Assign a task:

{
"name": "task.assign",
"params": {
"actor": "extension",
"taskText": "Drink water",
"points": 5,
"verificationRequired": false,
"durationSeconds": 900
}
}

This creates a TaskRun for the active lock. If another task run is already open, the current implementation cancels the old open run and creates a new one.

Start the active task timer:

{
"name": "task.start_timer",
"params": {}
}

Complete the active task:

{
"name": "task.complete",
"params": {
"successful": true
}
}

This completes the latest open TaskRun for the active lock.

Start a hygienic unlock:

{
"name": "hygienic_unlock.start",
"params": {
"durationSeconds": 900
}
}

End active pillory:

{
"name": "pillory.end",
"params": {}
}

Custom Lock Log

Use this when your program did something and you want it visible in lock history.

POST https://chastify.net/api/apps/v1/logs/custom

Example:

curl -X POST https://chastify.net/api/apps/v1/logs/custom \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Program check completed","description":"The external rule script ran successfully.","role":"extension"}'

Body fields:

  • title: required
  • description: optional
  • role: extension, wearer, or keyholder
  • icon: optional
  • color: optional hex color, for example #ffcc00

Device Commands

Device commands use the session device-command API when you are working with an extension session:

POST https://chastify.net/api/extensions/sessions/:sessionId/device-command

Supported command values:

  • shock.start
  • shock.stop
  • vibration.start
  • vibration.stop
  • all.stop
  • shock.random.set
  • shock.berserk.set

Device commands depend on the active lock, device availability, and command policy.

Common Errors

  • 401 missing_token: send Authorization: Bearer YOUR_DEV_TOKEN.
  • 401 invalid_token: the token is wrong or was copied incorrectly.
  • 401 revoked_token: the DEV key was revoked.
  • 403 insufficient_scope: the key does not have the required scope.
  • 409 no_active_lock_session: the user does not currently have an active lock.
  • 409 lock_ended: the resolved lock is no longer active.

Practical Pattern

Most external programs follow this flow:

  1. Call GET /api/apps/v1/session.
  2. Read lockData.
  3. Decide what should happen.
  4. Call /api/apps/v1/action or one of the simpler lock endpoints.
  5. Optionally write a custom log with /api/apps/v1/logs/custom.

For example, a script can check timeRemainingSeconds, add time when a rule fails, then write a custom log explaining what happened.