Webhooks
How to follow a build on app.vulk.dev, and the webhooks of the previous VULK workspace.
Webhooks
Following a build on app.vulk.dev
On https://app.vulk.dev/api/v1, every build or instruction has a requestId, and its state is read with GET /operations/:requestId. Reading is free, never starts or charges anything, and is safe to repeat, so the recipe is a short loop:
POST /projects(orPOST /projects/:id/messages) with arequestIdyou keep.GET /operations/:requestIdevery few seconds whileoperationStatusisrunning.- Act on the final state:
waitingmeans VULK asked a question — answer it with the next instruction;donemeans the version is delivered, withcurrentProjectPreviewUrland the files behindGET /projects/:id/files;failedandorphanmean no version was delivered.
A build takes from under a minute to several minutes depending on the brief; polling every 5 seconds stays far inside the limit of 60 requests per minute per key. The TypeScript client on the SDK page has this loop as waitFor.
An AI assistant connected over MCP runs the same loop with get_operation.
Webhooks of the previous VULK workspace
The previous VULK workspace at vulk.dev delivers HTTP webhooks for its own API (vulk.dev/api/v1) and the projects in that workspace. They are configured at Settings > Webhooks at vulk.dev/settings/webhooks:
- Click Create Webhook
- Enter your endpoint URL (must be HTTPS)
- Select the events you want to receive
- Click Create
You can have up to 10 webhooks per account there.
Events
| Event | Triggered When |
|---|---|
project.created | A new project is created |
project.updated | Project files are modified |
project.deleted | A project is deleted |
generation.started | AI generation begins |
generation.completed | Generation finishes successfully |
generation.failed | Generation encounters an error |
deploy.started | Deployment begins |
deploy.completed | App is live at its URL |
deploy.failed | Deployment encounters an error |
export.completed | Code export (ZIP or GitHub) finishes |
Payload
{
"event": "project.created",
"timestamp": "2026-04-02T15:30:00Z",
"data": {
"projectId": "abc123",
"name": "My App",
"userId": "user_xyz"
}
}Signature verification
Each delivery carries X-Vulk-Signature: sha256=…, an HMAC-SHA256 of the raw request body with the webhook's secret, shown once when the webhook is created:
const crypto = require('crypto');
function verifyWebhook(body, signature, secret) {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}Delivery logs, tests and retries
Every delivery is logged with the HTTP status of your endpoint, the response time, the headers and whether it succeeded; the log is behind each webhook in Settings > Webhooks, where Test sends a sample payload. Failed deliveries (non-2xx) are retried up to 3 times with exponential backoff.
Troubleshooting
- Not receiving webhooks — check that the endpoint URL is correct and answers 2xx over HTTPS, and read the delivery log.
- Signature mismatch — compute the HMAC over the raw request body, not the parsed JSON, with the secret of that webhook.