Build / API reference
Signals your deploy
already knows how to send.
DeployState accepts plain HTTP requests at every deployment handoff. Use a private step hook for the fastest setup, a friendly URL plus step key when people need to read the endpoint, or a personal access token for authenticated API access.
01 / Private step hooks
One URL is the credential.
Each step gets a unique 64-character random token. Treat the full URL like a deploy secret: keep it in your platform’s encrypted environment settings and never publish it in source control. If it leaks, rotate the private URL from the step editor.
02 / Friendly hook URLs
Readable to people. Private to everyone else.
Name a sequence and its steps for a cleaner command. The URL becomes readable; the step’s private token moves to a header, so it remains safe for curl, Forge, and CI secrets.
curl --fail --silent --show-error -X POST \
-H 'X-DeployState-Key: {step_token}' \
'https://deploystate.com/api/v1/{sequence_slug}/{step_slug}/start'
Set a sequence endpoint name, then one name per step, to make this endpoint live. Keep the header value in your deployment secret store.
03 / Copy a lifecycle
Start. Finish. Fail honestly.
Call /start immediately before the work begins. Call /complete only after it succeeds, or /fail with a useful error message.
curl --fail --silent --show-error -X POST 'https://deploystate.com/api/v1/hooks/{step_token}/start'
if ./deploy.sh; then
curl --fail --silent --show-error -X POST 'https://deploystate.com/api/v1/hooks/{step_token}/complete'
else
curl --fail --silent --show-error -X POST \
-H 'Content-Type: application/json' \
--data '{"message":"Deploy failed"}' \
'https://deploystate.com/api/v1/hooks/{step_token}/fail'
exit 1
fi
<?php
use Illuminate\Support\Facades\Http;
Http::post('https://deploystate.com/api/v1/hooks/{step_token}/start')->throw();
try {
runDeploy();
Http::post('https://deploystate.com/api/v1/hooks/{step_token}/complete')->throw();
} catch (Throwable $exception) {
Http::post('https://deploystate.com/api/v1/hooks/{step_token}/fail', [
'message' => $exception->getMessage(),
])->throw();
throw $exception;
}
const hook = 'https://deploystate.com/api/v1/hooks/{step_token}';
await fetch(`${hook}/start`, { method: 'POST' });
try {
await runDeploy();
await fetch(`${hook}/complete`, { method: 'POST' });
} catch (error) {
await fetch(`${hook}/fail`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: error.message }),
});
throw error;
}
Your selected hook is shown above.
04 / Personal access tokens
Use a bearer token for the authenticated API.
Tokens are for reading status, requesting a desktop realtime token, or acting on steps through the authenticated API. DeployState only shows a token once when you create it.
Authorization: Bearer YOUR_PERSONAL_ACCESS_TOKEN| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/v1/sequences/active | Current active runs you can access. |
| GET | /api/v1/sequences/recent | Recent completed or failed runs. |
| GET | /api/v1/ably/token | A short-lived realtime subscription token. |
| POST | /api/v1/{sequence}/{step}/start | Start a step with a personal token. |
| POST | /api/v1/{sequence}/{step}/complete | Complete a step with a personal token. |
| POST | /api/v1/{sequence}/{step}/fail | Fail a step with a personal token. |
05 / Responses
Minimal by default. Detailed when asked.
Successful hook calls return an empty body. Add Prefer: return=representation when your integration needs the updated sequence_log and step_log. The desktop app receives the matching state change through realtime either way.
curl -X POST -H 'Prefer: return=representation' 'https://deploystate.com/api/v1/hooks/{step_token}/start'- 201
- A new run started.
- 200
- An existing run or step changed state.
- 409
- The requested transition is not valid from the current state.
- 422
- The sequence is paused and cannot accept a new run.
- 404
- The private hook token or API resource does not exist.