Forms API
Everything the dashboard does with forms and responses - over a small REST API. Designed to be driven by an LLM.
✦ Use it from your LLM
Paste this into Claude, ChatGPT, or any agent. It points the model at the machine-readable spec and your key - no plugin to install.
You can manage my ava42 forms through its REST API. Base URL: https://ava42.com Auth: send header Authorization: Bearer YOUR_API_KEY Fetch and follow these first: - https://ava42.com/llms.txt (endpoints & examples) - https://ava42.com/schema.md (every field type) When I ask you to create or edit a form, or read its responses, call the /v1 API with my key above.
Get YOUR_API_KEY in Settings → API.
Authentication
Every /v1 request is authenticated with a per-org key sent as a Bearer token. All calls are scoped to that key's organization.
curl https://ava42.com/v1/forms \ -H "Authorization: Bearer ava_your_key_here"
Endpoints
| Method | Path | Does |
|---|---|---|
| GET | /v1/me | Your org & plan |
| GET | /v1/forms | List forms |
| POST | /v1/forms | Create a form (body: a form schema) |
| GET | /v1/forms/{id} | Get a form's schema |
| PUT | /v1/forms/{id} | Update a form |
| DEL | /v1/forms/{id} | Delete a form |
| GET | /v1/forms/{id}/submissions | Responses (JSON) |
| GET | /v1/forms/{id}/submissions.csv | Responses (CSV) |
| GET | /v1/members | List members & pending invites |
| POST | /v1/members | Invite a member (emails a link) |
| DEL | /v1/members/{email} | Remove a member |
Create a form
curl -X POST https://ava42.com/v1/forms \
-H "Authorization: Bearer ava_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"title": "Contact us",
"fields": [
{"type":"text","name":"name","label":"Your name","required":true},
{"type":"email","name":"email","label":"Email","required":true},
{"type":"select","name":"topic","label":"Topic","options":["Sales","Support"]},
{"type":"textarea","name":"message","label":"Message"}
]
}'File uploads
Add a file question and respondents can attach photos, PDFs and documents. No JavaScript required to upload - it is a native file input in a native form post.
{"type":"file","name":"photo","label":"A photo of the problem","required":true,"max":2}| Limit | Value |
|---|---|
| Per file | 20 MB, on every plan including Pro |
| Files per response | 3, across all file questions |
| Total per response | 30 MB |
| Accepted types | jpg, png, gif, webp, heic, pdf, doc(x), xls(x), pptx, csv, txt |
Every upload is checked twice: the extension must be allowed, and the file's first bytes must match the format it claims. A .png that is really an executable is refused, because the person who opens it is you.
Files never appear in the response JSON - that holds the filename. The bytes are downloadable only by signed-in members of your organisation, from /app/files/{id}, always as an attachment with a content type we set. An uploaded HTML or SVG file can never execute as a script.
Prefill a question from the URL
Add a query parameter named after a question and it arrives filled in. No setup and no hidden fields.
The parameter is the question's name, not its label. You never have to guess it: open a form in the app and press Share & embed, where every parameter is listed beside its question with a button that builds the link. Programmatically, read fields[].name from GET /v1/forms/{id}. A name is derived from the label the first time a form is saved and then pinned, so renaming a question later changes neither its parameter nor where its existing answers live.
https://ava42.com/f/[email protected]&plan=Pro&topics=Sales,Support
| Field type | What to put in the URL |
|---|---|
| text, email, number, tel, url, date, textarea | the value |
| select, radio | a value matching one of its options exactly |
| checkbox | 1, yes, true or on to tick it |
| multichoice | comma-separated option values |
| rating, scale | the number |
| file | cannot be prefilled - a browser only lets a person choose a file, so no link can attach one for them. The parameter is ignored. |
Three rules worth knowing. The respondent's answer always wins - a parameter only fills a question they left blank, so an edit is never overwritten. A URL can't tick a box on someone's behalf: if the browser didn't submit that field at all, the parameter is ignored, because consent has to be given rather than linked. And it degrades - with JavaScript off nothing appears prefilled, but the value still reaches the server for any blank question.
A parameter that matches no question is stored with the response anyway, which is how ?utm_source=newsletter and ?lead_id=42 work with no fields to define.
Embed a form in your site
One iframe and a few lines of script that resizes it as the form changes. The snippet is generated for you in your dashboard - open a form and press Share & embed.
<iframe src="https://ava42.com/f/your-slug" title="Contact us"
style="width:100%;border:0;height:600px" loading="lazy"></iframe>
<script>addEventListener("message",function(e){
if(e.origin!=="https://ava42.com"||!e.data||e.data.ava!=="height")return;
var f=document.querySelector('iframe[src*="/f/your-slug"]');
if(f)f.style.height=e.data.height+"px";
});</script>A framed form drops its page background and centring so it sits flush in your layout, and posts its height to the parent whenever it changes - on load, on a validation error, and on each step of a multi-step form. Without the script it still works; you just pick the height yourself.
Machine reference: /llms.txt · Full field schema: /schema.md