Skip to content

Surfaces (Ingest · Events)

The HTTP API is the request/response surface. Two more surfaces close the loop — so the agent can be fed from where product intent already lives, and can notify your systems when something happens.

Each is its own thin Worker or module on top of the same control plane. Nothing here is a second copy of the API — every surface funnels back through the same auth and logic.

Register an ingest source and anything that can sign an HTTP request can post an idea into a project (which becomes a ticket) — so work flows in from wherever it already lives, instead of being re-entered by hand.

Create a source (session-only; returns the secret + URL once):

Terminal window
curl -X POST https://<your-api-host>/api/v1/ingest \
-H 'content-type: application/json' \
--cookie "$SESSION" \
-d '{ "projectId": "prj_…" }'
# → { "ok": true, "data": { "id": "ing_…", "secret": "whsec_…",
# "webhookUrl": "https://hooks.typillar.com/i/ing_…" } }

POST a signed JSON body of { title, text, id?, url? } to webhookUrl. Requests hit the ingress Worker (hooks.typillar.com), which verifies the signature and hands the idea to the control plane. Reusing id returns the idea already captured, so a retry cannot duplicate a ticket.

See Webhooks for the signature scheme, the status codes, idempotency, and verification code you can copy.

Subscribe a webhook endpoint to lifecycle events and Typillar POSTs each one to your URL — so a deploy can notify Slack, or a build result can kick a downstream job.

Terminal window
curl -X POST https://<your-api-host>/api/v1/webhooks \
-H 'content-type: application/json' \
--cookie "$SESSION" \
-d '{ "url": "https://example.com/hook", "events": ["project.deployed","project.reverted"] }'
# → { "ok": true, "data": { "id": "whe_…", "secret": "whsec_…" } }

The event types, in full — use ["*"] for all of them:

Event Fires when
project.created a project is created
ticket.created a ticket is opened, however it arrived
ticket.updated a ticket’s fields change
ticket.build.succeeded a build finishes and produces an app
ticket.build.failed a build fails
project.deployed a Deployment goes live
project.rolled_back a Deployment is rolled back — a live release taken off its URL
project.reverted the code is restored to an earlier version
project.renamed a project is renamed
project.archived a project is archived — taken offline, its data kept
project.deleted a project is deleted

project.reverted is Restore and project.rolled_back is Roll back — different acts, different events. See Webhooks.

Each POST carries a Typillar-Signature header and an EventEnvelope body:

{ "id": "evt_…", "type": "project.deployed", "projectId": "prj_…",
"createdAt": 1751000000000, "data": { "url": "https://…" } }

Every endpoint receives this same signed envelope. To forward events into a chat tool, post them on from your own handler.

Delivery is at-least-once and retried. See Webhooks for verification code, the retry policy, and why you must deduplicate on Typillar-Delivery-Id.

All three surfaces funnel back through the same control plane, so each one enforces the same authentication, scopes, and validation as the HTTP API — there’s no weaker second door, and no rules to keep in sync across surfaces. Outbound event delivery is durable and retried, so a brief outage on your side doesn’t lose events.