Veldform / Docs
Custom API's
Veldform talks to APIs in both directions: it can send entry data to any API on submit, and it can pull data from an API to populate options or prefill values. Credentials for all of this live in connections.
- Sending data to an API
- Populating options from an API
- Prefilling field values
- Prefilling a whole form
Sending data to an API
Add the Send to external API action to your form. It has the following settings:
Connection
Optional — pick a saved connection. Its base URL is prepended to the endpoint and its auth headers are added to the request. This is how you handle authentication: API keys, Bearer tokens, Basic auth and OAuth2 are all configured on the connection, not on the action.
You can also leave it at None and use a full URL instead.
Endpoint URL and method
The URL (or path, when using a connection) to send to. Merge tags are allowed. The method can be POST, PUT, PATCH or DELETE.
Body
Three options:
- Entry as JSON — sends
{ "form_id": ..., "entry_id": ..., "data": { ... } } - Entry as form-encoded — the same data, form-encoded
- Custom — a Liquid template, for when the API expects a specific shape
With a custom body, use the json filter on every value — it quotes and escapes strings and leaves numbers and booleans bare, so your JSON stays valid:
{
"email": {{ field.f_email | downcase | json }},
"firstname": {{ raw.f_name.first | json }},
"guests": {{ field.f_guests | to_int | json }}
}
Custom headers
Under Advanced you can add headers, one per line as Name: value. Merge tags are allowed here too.
Capture from response
You may store parts of the API response as outputs. Define an output key and the path in the response — if your API responds with { "data": { "id": 123 } }, a capture of order_id <- data.id makes the value available as {{ output.order_id }} in later actions, notifications and the confirmation message.
Required
When enabled, a failed request aborts the submission and the visitor sees an error instead of the confirmation. When disabled, failures are logged and the submission continues.
A few things the action does for you: requests get an Idempotency-Key header (so retries don't create duplicates), time out after 15 seconds, and failed requests are logged with request and response details — check Veldform -> Log when something doesn't arrive. Requests to internal/private hosts are blocked by default as a security measure (see the veldform/webhook/allow_internal filter if you genuinely need this).
Populating options from an API
Dropdown, multiple choice and checkbox fields can load their options from an API instead of a static list. In the field settings, set Options source to From API:
- Connection — or a full URL
- URL or path — merge tags allowed, e.g.
/wp/v2/posts/{{ field.f_other }} - Items path — the dot-path to the array in the response, e.g.
data.items - Label field and Value field — which keys of each item to use
- Load —
On page load, orWhen a field changesfor dependent (cascading) dropdowns
There's a Test the request panel that runs the request live and shows the options it would produce, so you can verify your paths before saving.
Responses are cached for 5 minutes by default.
Prefilling field values
Text-like fields (text, email, number, phone, website, date and time) have a Prefill from API chip in their settings. It fetches a record when a trigger field changes (on blur or on change) and maps response values to fields.
Say you want to look up a customer by their email address: set the email field as trigger, fetch /customers/{{ field.f_email }}, and map name -> f_name and company -> f_company.
Prefilling a whole form
On the form's Settings tab you'll find Prefill from API: one fetch when the form loads, typically keyed off a URL parameter, that fills multiple fields. For example, an edit form that loads /wp/v2/posts/{{ query.post_id }} and maps title.rendered -> f_title.
Use {{ query.name }} for URL parameters and {{ user.email }} (or other user properties) for the logged-in visitor. The fetch is skipped when a referenced query parameter is missing.
Restricting access
When you prefill from a URL parameter, you usually don't want visitors editing other people's records by changing the parameter. That's what Restrict to matching records is for: rules that the fetched record must match, like response.author is {{ user.id }}. When the rules don't match, you choose what happens: show a message, or hide the form.
This guard is enforced on the server — at render, and again on submit.