APIs e programas externos
Use esta página quando desejar que um programa externo simples, um script, um servidor local ou um serviço de backend controle seu bloqueio Chastify atual.
A maneira mais fácil é criar um token DEV válido para todo o usuário e, em seguida, enviá-lo como um token de portador para os endpoints /api/apps/v1/*.
/api/apps/v1/* destina-se apenas às suas próprias sessões de bloqueio ativas. Se estiver a criar uma extensão pública utilizada por outros utilizadores de Chastify, utilize uma chave de API de desenvolvedor com escopo de aplicativo com /api/extensions/sessions/:sessionId/* e passe o iframe mainToken em x-chastify-main-token.
Criar um token DEV
- Abra Chastify.
- Acesse
Developer API. - Encontre
User-wide DEV API keys. - Criar uma chave.
- Copie o token imediatamente. Ele só é exibido uma vez.
Use-o em solicitações como esta:
curl https://chastify.net/api/apps/v1/session \
-H "Authorization: Bearer YOUR_DEV_TOKEN"
Tokens DEV:
- não exigem a criação de uma extensão
- não expira automaticamente
- Funciona para sua fechadura ativa atual e para futuras sessões de fechadura ativa.
- Use sua função na fechadura ativa, seja usuário ou detentor da chave.
- pode ser revogado na página da API do desenvolvedor.
Trate o token DEV como uma senha. Qualquer pessoa que possua o token pode acessar a API de desenvolvedor em seu nome.
Primeiro passo: Verificar a fechadura atual
Comece por:
GET https://chastify.net/api/apps/v1/session
Exemplo:
curl https://chastify.net/api/apps/v1/session \
-H "Authorization: Bearer YOUR_DEV_TOKEN"
Isso retorna seu contexto de bloqueio atual, função, escopos, tempo restante e lockData.
Auxiliares de bloqueio de dados
GET /api/apps/v1/session inclui lockData, que foi projetado para ser fácil de ler para programas e mecanismos de regras.
Booleanos comuns:
frozenunlockabletrustedtaskAssigned:truequando a fechadura ativa tem umTaskRunaberto
Números comuns:
timeLockedSecondstimeRemainingSecondsmaxTimeRemainingSecondstaskPoints
Cadeias comuns:
lockTitle- campos do perfil do usuário
- Campos do perfil do responsável pela chave
Nota sobre privacidade:
wearerLastSeenTimestampekeyholderLastSeenTimestampsãonullquando o usuário desativou o status online.
Pontos finais da ação de bloqueio principal
Esses são os pontos de extremidade que a maioria dos programas externos utiliza para modificar um bloqueio.
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
Todas as solicitações utilizam:
Authorization: Bearer YOUR_DEV_TOKEN
Content-Type: application/json
Adicionar ou remover tempo
Use o endpoint de tempo simples quando você quiser alterar apenas o tempo restante.
Acrescente 10 minutos:
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}'
Remover 5 minutos:
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}'
Congelar e descongelar
Congele por 30 minutos:
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}'
Descongelar:
curl -X POST https://chastify.net/api/apps/v1/lock/unfreeze \
-H "Authorization: Bearer YOUR_DEV_TOKEN"
Ponto final de ação geral
Usar:
POST https://chastify.net/api/apps/v1/action
Tipo físico:
{
"name": "add_time",
"params": 600
}
Exemplo:
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}'
Nomes de ações suportados
name suporta:
add_timeremove_timefreezepilloryunfreezetoggle_freezesettings.patchtask.assigntask.start_timertask.completehygienic_unlock.startpillory.end
Restrições de ação:
- As ações de tarefas exigem que o módulo Tarefas esteja ativado na fechadura.
hygienic_unlock.startrequer que a Abertura Higiênica esteja ativada e que não haja nenhuma sessão de higiene ativa.- Os comandos do dispositivo exigem um dispositivo conectado compatível e permissões adequadas.
Exemplos de ações úteis
Remova 15 minutos:
{
"name": "remove_time",
"params": 900
}
Congele por 5 minutos:
{
"name": "freeze",
"params": {
"durationSeconds": 300
}
}
Alternar congelamento:
{
"name": "toggle_freeze",
"params": {
"durationSeconds": 300
}
}
Atribua uma tarefa:
{
"name": "task.assign",
"params": {
"actor": "extension",
"taskText": "Drink water",
"points": 5,
"verificationRequired": false,
"durationSeconds": 900
}
}
Isso cria um código TaskRun para o bloqueio ativo. Se outra execução de tarefa já estiver aberta, a implementação atual cancela a execução antiga e cria uma nova.
Inicie o cronômetro da tarefa ativa:
{
"name": "task.start_timer",
"params": {}
}
Conclua a tarefa ativa:
{
"name": "task.complete",
"params": {
"successful": true
}
}
Isso conclui a abertura mais recente do TaskRun para a fechadura ativa.
Comece um desbloqueio higiênico:
{
"name": "hygienic_unlock.start",
"params": {
"durationSeconds": 900
}
}
Fim do pelourinho ativo:
{
"name": "pillory.end",
"params": {}
}
Registro de bloqueio personalizado
Use isso quando seu programa executar alguma ação e você quiser que ela seja visível no histórico de bloqueios.
POST https://chastify.net/api/apps/v1/logs/custom
Exemplo:
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"}'
Campos corporais:
title: obrigatóriodescription: opcionalrole:extension,weareroukeyholdericon: opcionalcolor: cor hexadecimal opcional, por exemplo#ffcc00
Comandos do dispositivo
Os comandos do dispositivo permitem acionar choques e vibrações no dispositivo conectado do usuário.
POST https://chastify.net/api/apps/v1/device-command
Funciona com seu token DEV — sem necessidade de ID de sessão. O servidor resolve automaticamente a fechadura e o usuário a partir do seu token.
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.start","params":{"intensityPct":75,"durationSeconds":10}}'
Corpo da solicitação
{
"command": "<command>",
"params": { ... }
}
command(string, obrigatório) — o comando do dispositivo a ser executado.params(objeto, opcional) — parâmetros específicos do comando (veja abaixo).
Comandos suportados e seus parâmetros
shock.start
Inicia um choque no dispositivo do usuário.
| Parâmetro | Tipo | Intervalo | Padrão | Descrição |
|---|---|---|---|---|
intensityPct | número | 1–100 | 50 | Shock intensidade em porcentagem |
durationSeconds | número | 1–300 | 60 | Shock duração em segundos |
message | string | — | — | Mensagem opcional exibida ao usuário |
A tensão máxima configurada pelo usuário é sempre aplicada como um limite rígido, independentemente do que você enviar. Para dispositivos Lockink, este é o limite de tensão por dispositivo. Para dispositivos QIUI, este é o limite de tensão shockVolt (escala de 1 a 4). Se você enviar intensityPct: 80, mas o limite do usuário for de 50%, o dispositivo fornecerá apenas 50%.
Exemplo:
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.start","params":{"intensityPct":75,"durationSeconds":10,"message":"Extension shock"}}'
shock.stop
Interrompe todos os choques ativos no dispositivo do usuário. Não requer parâmetros.
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.stop"}'
vibration.start
Inicia uma vibração no dispositivo do usuário.
| Parâmetro | Tipo | Intervalo | Padrão | Descrição |
|---|---|---|---|---|
intensityPct | número | 1–100 | 50 | Intensidade de vibração em porcentagem |
durationSeconds | número | 1–300 | 30 | Duração da vibração em segundos |
frequencyPct | número | 1–100 | 50 | Frequência de vibração em porcentagem |
message | string | — | — | Mensagem opcional exibida ao usuário |
Exemplo:
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"vibration.start","params":{"intensityPct":60,"durationSeconds":15,"frequencyPct":40}}'
vibration.stop
Interrompe todas as vibrações ativas. Não requer parâmetros.
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"vibration.stop"}'
all.stop
Interrompe toda a atividade do dispositivo (choques, vibrações, etc.). Não requer parâmetros.
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"all.stop"}'
shock.random.set
Ativa ou desativa o modo de choque aleatório no dispositivo do usuário.
| Parâmetro | Tipo | Intervalo | Padrão | Descrição |
|---|---|---|---|---|
enabled | booleano | — | — | Ativar (true) ou desativar (false) o modo aleatório |
minIntensityPct | número | 1–100 | 20 | Percentagem mínima de intensidade de choque |
maxIntensityPct | número | 1–100 | 80 | Percentagem máxima de intensidade do choque |
message | string | — | — | Mensagem opcional exibida ao usuário |
A voltagem máxima configurada para o usuário é sempre o limite máximo. Se você definir maxIntensityPct: 80, mas o limite do usuário for 50, o máximo real será 50%.
Exemplo:
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.random.set","params":{"enabled":true,"minIntensityPct":25,"maxIntensityPct":75}}'
shock.berserk.set
Ativa ou desativa o modo de choque berserk no dispositivo do usuário.
| Parâmetro | Tipo | Intervalo | Padrão | Descrição |
|---|---|---|---|---|
enabled | booleano | — | — | Ativar (true) ou desativar (false) o modo berserk |
message | string | — | — | Mensagem opcional exibida ao usuário |
Exemplo:
curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.berserk.set","params":{"enabled":true}}'
Os comandos do dispositivo dependem da fechadura ativa, da disponibilidade do dispositivo e da política de comandos.
Seleção de dispositivo
Não é necessário especificar um ID de dispositivo ou tipo de dispositivo. Cada usuário só pode ter um dispositivo ativo por vez — o servidor o identifica automaticamente.
O código deviceType é retornado na resposta para que você saiba qual dispositivo recebeu o comando.
Respostas
Sucesso (200)
{
"ok": true,
"command": "shock.start",
"result": {
"success": true,
"message": "Shock command sent (10s)",
"deviceType": "lockink-aa-a1012"
},
"active": {
"shock": true,
"vibration": false
}
}
| Campo | Descrição |
|---|---|
ok | true quando o comando foi aceito |
command | O comando que foi executado |
result.success | true se o dispositivo confirmou o comando |
result.message | Mensagem de status legível por humanos |
result.deviceType | Tipo de dispositivo do usuário (ex.: lockink-aa-a1012, cellmate-pro-3) |
active.shock | Indica se há algum choque ativo no dispositivo do usuário |
active.vibration | Indica se há vibração ativa no dispositivo do usuário |
Nota: Os comandos shock.start e vibration.start aguardam até 25 segundos para que o dispositivo confirme o recebimento. Os comandos de parada (shock.stop, vibration.stop, all.stop) retornam imediatamente.
Falha
Todas as falhas retornam HTTP 4xx/5xx com um corpo JSON:
{
"success": false,
"error": "no_device",
"message": "No shock-capable device found for user"
}
| Cenário | HTTP | error | message |
|---|---|---|---|
| Fechadura não encontrada ou nenhuma fechadura ativa | 404 | lock_not_found | No active lock found |
| O bloqueio não está mais ativo | 409 | lock_ended | The lock is no longer active |
| Sessão do usuário ausente | 400 | no_wearer | Missing wearer session |
durationSeconds ausente ou inválido | 400 | invalid_params | durationSeconds is required for server-initiated shocks |
| Modo aleatório/berserk em dispositivo não compatível | 400 | unsupported_device | Random mode only supported on Lockink AA-A1012 |
| O usuário não concedeu consentimento para choque | 403 | not_authorized | User not eligible for shock commands (consent or device check failed) |
| Nenhum dispositivo compatível com choque/vibração emparelhado | 404 | no_device | No shock-capable device found for user |
| Dispositivo offline (sem conexão de soquete) | 404 | device_offline | No active device socket found for user |
| O dispositivo não confirmou a tempo (25s) | 504 | device_timeout | Device verification timeout |
| Falha não reconhecida ou não tratada | 400 | command_failed | command_failed |
Quando disponível, deviceType é incluído na resposta.
Explicação dos cenários de falha mais comuns
O dispositivo deve estar conectado através do aplicativo móvel.
O uso do Shock e suas vibrações requer que o usuário tenha um dispositivo Bluetooth compatível emparelhado e o aplicativo móvel Chastify em execução no celular. O aplicativo mantém a conexão de socket em tempo real que envia os comandos para o dispositivo. Se o aplicativo for fechado ou o celular estiver sem internet, os comandos falharão.
no_device — O usuário não emparelhou um dispositivo com capacidade de detecção de choque (por exemplo, CellMate Pro 3, Cagink Metal, Lockink AA-A1012) no aplicativo Chastify. Os dispositivos devem ser emparelhados, estar ativos e totalmente configurados para que a API possa acessá-los.
device_offline — O dispositivo do usuário está emparelhado, mas o Serviço Nativo Shock não está ativado ou não está em execução no aplicativo Android. Esta é a falha mais comum — o usuário precisa ter o Serviço Nativo Shock ativado nas configurações do aplicativo Android para que os comandos sejam entregues de forma confiável.
device_timeout — O comando foi enviado para o aplicativo móvel, mas o aplicativo não confirmou que o dispositivo Bluetooth o recebeu em 25 segundos. Isso geralmente significa que o Bluetooth do usuário está desligado, o dispositivo está fora do alcance ou está desligado. Dispositivos Lockink entram em modo de espera após apenas 3 minutos de inatividade, a menos que a função keep-alive esteja ativada — e mesmo assim, as otimizações de bateria do fabricante do telefone podem restringir o Bluetooth em segundo plano e impedir que o keep-alive funcione corretamente.
not_authorized — O usuário não concedeu consentimento explícito para choques nas configurações do dispositivo. Este é um requisito de segurança — mesmo com um dispositivo emparelhado, o usuário deve optar por permitir comandos remotos de choque/vibração.
unsupported_device — Os modos aleatório e berserk estão disponíveis apenas no Lockink AA-A1012 (Beesting). Outros dispositivos, como o CellMate Pro 3 ou o Cagink Metal, não são compatíveis com esses modos.
Erros comuns
401 missing_token: enviarAuthorization: Bearer YOUR_DEV_TOKEN.401 invalid_token: o token está incorreto ou foi copiado incorretamente.401 revoked_token: a chave DEV foi revogada.403 insufficient_scope: a chave não possui o escopo necessário.409 no_active_lock_session: o usuário não possui nenhum bloqueio ativo no momento.409 lock_ended: o bloqueio resolvido não está mais ativo.
Entendendo device_timeout (504)
O erro device_timeout significa que o servidor enviou o comando de choque para o aplicativo Android do usuário, mas o aplicativo não confirmou o recebimento pelo dispositivo Bluetooth em 25 segundos. Este é o erro mais complexo — veja o que acontece no lado do Android:
- Servidor → Aplicativo: O comando é transmitido via Socket.IO para o serviço nativo Shock em execução no telefone do usuário.
- Aplicativo → Dispositivo: O aplicativo se conecta ao dispositivo via Bluetooth Low Energy (BLE) e envia o comando de choque. Para dispositivos QIUI, isso envolve primeiro obter um token da API do fabricante do dispositivo e, em seguida, escrever o comando BLE. Para dispositivos Lockink, o comando BLE é enviado diretamente.
- Aplicativo → Servidor: O aplicativo envia uma confirmação de volta para o servidor.
O tempo limite de 25 segundos começa na etapa 1. Um tempo limite na etapa 2 pode ocorrer porque:
- O Bluetooth está desligado ou o dispositivo está fora do alcance do telefone do usuário.
- O dispositivo está em modo de hibernação. Os dispositivos Lockink entram em hibernação profunda após apenas 3 minutos de inatividade BLE. O recurso de manter a conexão ativa pode evitar isso, mas as otimizações de bateria dos fabricantes (Samsung, Xiaomi, Huawei, etc.) podem encerrar as conexões Bluetooth em segundo plano, tornando a função de manter a conexão ativa instável.
- Falha na conexão BLE. O aplicativo tenta novamente a conexão BLE, mas se o dispositivo não responder, a conexão expira.
- Bloqueio de segurança. O aplicativo possui um sistema de segurança integrado que bloqueia os choques se o usuário for detectado em movimento (por exemplo, dirigindo ou pedalando), com base no reconhecimento de atividade e na velocidade do GPS. Se o usuário estiver em movimento, o choque é bloqueado silenciosamente e relatado como falha.
- Falha na obtenção do token QIUI. Para dispositivos CellMate Pro 3 e Cagink, o aplicativo precisa obter um token de comando da API em nuvem do QIUI antes de enviar o comando BLE. Se o telefone do usuário não tiver internet ou se a API do QIUI estiver lenta ou inacessível, essa etapa pode consumir a maior parte do intervalo de 25 segundos.
Padrão prático
A maioria dos programas externos segue este fluxo:
- Ligue para
GET /api/apps/v1/session. - Leia
lockData. - Decida o que deve acontecer.
- Chame
/api/apps/v1/actionou um dos endpoints de bloqueio mais simples. - Opcionalmente, escreva um log personalizado com
/api/apps/v1/logs/custom.
Por exemplo, um script pode verificar timeRemainingSeconds, adicionar o tempo em que uma regra falha e, em seguida, escrever um log personalizado explicando o que aconteceu.