API and agents
Everything the dashboard does goes through the same API. Scripts and agents can use it with a personal API key. They act as you, and the forms they create show up in your dashboard.
The full contract for agents is at /llms.txt. Point an agent at it. This page covers the same ground for people.
Create an API key
Section titled “Create an API key”- Go to Settings → API keys.
- Give the key a name, such as “My agent”, and click Create key.
- Copy the key. It is shown once.
Keys start with probe_. Probe stores only a hash of each key. The list shows each key’s prefix, when it was created and when it was last used.
Send the key on every request, with either header:
Authorization: Bearer probe_xxxxxxxxxxxxxxxxX-API-Key: probe_xxxxxxxxxxxxxxxxKeys do not expire. They stop working when you click Revoke. Treat them like passwords.
An API key cannot create or revoke API keys. Those calls need a signed-in dashboard session. apiKeys.list works with a key.
How the API works
Section titled “How the API works”The API is tRPC over HTTP at /trpc/<router>.<procedure>. It uses the superjson transformer, so inputs and outputs are wrapped in {"json": …}.
| Request | |
|---|---|
| Query (read) | GET /trpc/<proc>?input=<url-encoded {"json":{…}}> |
| Mutation (write) | POST /trpc/<proc> with body {"json":{…}} |
A success looks like {"result":{"data":{"json": …}}}. An error looks like {"error":{"json":{"message":"…","data":{"code":"NOT_FOUND"}}}}. Codes include UNAUTHORIZED, BAD_REQUEST, NOT_FOUND and TOO_MANY_REQUESTS. Resources you do not own return NOT_FOUND, not FORBIDDEN.
The interactive reference is at /api/docs. The OpenAPI spec is at /openapi.json.
Recipe: build and publish a form
Section titled “Recipe: build and publish a form”Set your key and base URL first:
export PROBE=https://probe.jahazi.cityexport PROBE_API_KEY=probe_xxxxxxxxxxxxxxxx1. Pick a theme
Section titled “1. Pick a theme”curl -s "$PROBE/trpc/themes.list"Take an id from the result.
2. Create the form
Section titled “2. Create the form”curl -s -X POST "$PROBE/trpc/forms.create" \ -H "Authorization: Bearer $PROBE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"json":{"title":"Feedback","themeId":"<theme-uuid>","visibility":"unlisted"}}'The result has the form’s id and slug. You can also pass description and a custom slug.
3. Add fields
Section titled “3. Add fields”Call fields.create once per field, with an increasing order:
curl -s -X POST "$PROBE/trpc/fields.create" \ -H "Authorization: Bearer $PROBE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"json":{"formId":"<form-uuid>","type":"short_text","label":"Your name","required":true,"order":0,"config":{}}}'
curl -s -X POST "$PROBE/trpc/fields.create" \ -H "Authorization: Bearer $PROBE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"json":{"formId":"<form-uuid>","type":"single_select","label":"Plan","order":1,"config":{"options":[{"label":"Free","value":"free"},{"label":"Pro","value":"pro"}]}}}'Field types: short_text, long_text, email, number, phone, url, single_select, multi_select, checkbox, rating, linear_scale, ranking, date, time, address, signature, file_upload (only when storage is configured) and page_break.
Common config keys: options, maxRating, ratingStyle (star, number or emoji), min, max, step, minLength, maxLength, scaleMin, scaleMax, scaleMinLabel, scaleMaxLabel, hidden, prefillKey. Unknown keys are rejected.
To show a field only when earlier answers match, add conditionalLogic:
{"conditionalLogic":{"showIf":[{"fieldId":"<field-uuid>","operator":"equals","value":"pro"}]}}Operators are equals, not_equals, contains, is_filled and is_empty. All rules must pass.
4. Publish
Section titled “4. Publish”curl -s -X POST "$PROBE/trpc/forms.publish" \ -H "Authorization: Bearer $PROBE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"json":{"id":"<form-uuid>"}}'The form is live at $PROBE/f/<slug>.
5. Read responses
Section titled “5. Read responses”curl -s -G "$PROBE/trpc/responses.list" \ -H "Authorization: Bearer $PROBE_API_KEY" \ --data-urlencode 'input={"json":{"formId":"<form-uuid>","limit":25}}'Hosted-form answers are in items[].values[], each with a fieldId and value. Endpoint-form submissions are in items[].payload. Add from and to as ISO datetimes to filter by date.
Or download a file:
curl -s -H "Authorization: Bearer $PROBE_API_KEY" \ -o responses.csv "$PROBE/forms/<form-uuid>/export.csv".xlsx and .pdf work the same way.
Let AI draft the form
Section titled “Let AI draft the form”If ai.status returns hasKey: true, one call creates a full draft:
curl -s -X POST "$PROBE/trpc/ai.generateForm" \ -H "Authorization: Bearer $PROBE_API_KEY" \ -H "Content-Type: application/json" \ -d '{"json":{"prompt":"A feedback form with a 1-5 rating, what they liked, and an optional email","themeId":"<theme-uuid>"}}'It returns {id, slug, fieldCount}. Review the fields, then publish. See AI form generation.
Other things you can do
Section titled “Other things you can do”- Form settings.
forms.updatetakessettings,maxResponsesandexpiresAt(the close date).forms.setPasswordsets or clears a password. - Endpoint forms.
endpoint.createreturns anaccessKey.endpoint.updatesets allowed origins andendpointSettings, such asallowServerSideandwebhookUrl.endpoint.getreturns the webhook signing secret. See Endpoint forms. - Submitting.
/submitneeds no API key, only the form’s access key. Hosted forms take public submissions throughpublic.submitResponse. - Analytics.
forms.getAnalyticsreturns views, starts, completion rate and a daily series.
What /llms.txt covers
Section titled “What /llms.txt covers”/llms.txt is written for agents. It explains:
- Which surface to use: an endpoint form to collect submissions, hosted forms for a themed page, or
responses.listto read results. - The
/submitcontract: body fields, error codes, the origin allowlist, server-side submissions, verification and webhook signatures. - API key authentication and the session-cookie fallback.
- The tRPC wire format with query and mutation examples.
- Recipes for creating and publishing a form, drafting one with AI, submitting to a hosted form, creating an endpoint form, and reading results.
- An index of every router and procedure.
If you run your own instance, /llms.txt is served from it too. Its examples use https://probe.jahazi.city. Tell the agent to use your origin instead.