REDA Data Service: Connect Your Forms
Every form you run outside REDA — a marketing-site contact form, a campaign landing page, a Webflow microsite — can create or update a REDA record the instant it's submitted, campaign attribution and all, with no code to write. The Data Service is REDA's packaged inbound web-intake engine: your form sends a small web request, REDA checks it against a permission row you control, and a mapping you configure turns the incoming values into a real record. This article is written for the administrator or web developer wiring that connection. It shows you how to build the address your form posts to, how to authenticate the request, how to shape the body, the ready-made set of fields that flow into a web inquiry, and where a failed submission goes so you can find and fix it. This is developer-facing content, so — unlike the rest of the Help Center — it shows the literal web addresses and request fields you'll need.
Access you'll need. Turning the service on and defining what it accepts is administrator configuration. Viewing the Async Logs to troubleshoot requires the REDA - Master Data - Read Only permission set (or a set that grants it). The endpoint itself is called by your website through a public guest connection your administrator sets up — no REDA login is needed on the form's side.
How it works
The Data Service accepts a web request from your form, confirms it's allowed, and hands it off to be turned into a record. The key design point is that acceptance and record creation are two separate moments:
Because acceptance and creation are decoupled, a success reply means "your request was accepted", not "the record now exists". Almost every submission does become a record; the rare failures during that background step are captured in the Async Log rather than lost, which is why the log is your safety net (see When something fails).
The background step is near-instant for a single submission and processes one submission at a time when many arrive at once, so under a burst — a campaign email blast, say — records may appear a short moment after their success replies rather than all at once. This is normal and doesn't drop anything; every accepted request is either written or logged.
Enabling and gating
Before any form can create records, four things line up. Every request — whether it's a browser-style read request or a form submission — passes the same gate:
| Gate | What it checks |
|---|---|
| Master switch | The Data Service must be switched on for the org. It is on in a standard REDA org; if it's off, requests are rejected with a "disabled" message. |
| Target record type | The kind of record named in the address (for example, an inquiry) must exist. |
| Per-record-type permission | A Setup row for that record type must allow the request: it carries separate switches for read and submit requests, plus separate Create Record and Edit Record switches. |
| Authentication | When the Setup row has an Auth Key set, the request must carry a matching key header — otherwise REDA rejects it with a 401 unauthorized response. |
Out of the box, one record type is wired up and open for business: the Inquiry — REDA's record for a prospect who has reached out — with read, submit, create, and edit all enabled and an auth key in place. A second record type, the Service Request, ships parked: its Setup row exists but every switch is off, so it accepts nothing until an administrator turns it on. Adding your own record types follows the same pattern, covered in Adding Data Service Objects & Sources.
The endpoint
Your form posts to a web address that names the record type you're creating and the data source — a label that groups one family of forms so its mappings stay separate from another's. The address follows this shape:
<Your Site URL>/services/apexrest/reda1/dataservice/<Record Type>/<Data Source>
For the shipped web-inquiry intake, the record type is the Inquiry and the data source is Web, giving an address that ends:
.../dataservice/reda1__Inquiry__c/Web
The first part — your site URL — is the public web address your administrator set up to expose the service; ask them for it. A successful request returns a 200 reply carrying {"success": true} straight away. If a gate check fails you get a 400 reply with a short message explaining why, and if the master switch is off you get a 400 with a "disabled" message.
The request
A form submission is a POST request. Its body is a small list of key/value pairs — one entry per field you're sending — written as JSON:
[
{"key": "FirstName", "value": "Aisha"},
{"key": "LastName", "value": "Rahman"},
{"key": "Email", "value": "aisha@example.com"}
]
When the Setup row requires authentication, the request also carries the key in a header named x-api-key. (A read-style GET request works the same way, with the values passed as address parameters instead of a body; forms should POST.)
Whether a request creates a new record or updates an existing one is decided by one field: recordId.
| Your request | What REDA does | Needs |
|---|---|---|
No recordId included | Creates a new record | Create Record switched on |
recordId included | Updates that existing record | Edit Record switched on |
Send a recordId when Edit Record is off (or a create when Create Record is off) and REDA answers "DML Operation not supported." — it's telling you the operation you asked for isn't enabled on that Setup row.
The shipped website integration
A mapping is the translation table between the keys your form sends and the fields on the REDA record. REDA ships a complete mapping for web inquiries: 21 parameters that cover the visitor's details, where they came from, and the full marketing attribution set. Send any of these keys in your request and they land on the right inquiry field. Two of them carry a default, applied when your form omits the value:
| Group | Keys you can send | Lands on | Default |
|---|---|---|---|
| Contact | FirstName, LastName, Email, Phone | Name, email, and phone | — |
| Company | Company | Company | --NA-- |
| Source | LeadSource | Inquiry Source | Web |
| Update key | recordId | The record to update | — |
| Campaign (UTM) | utm_campaign, utm_content, utm_id, utm_medium, utm_source, utm_term | The six UTM fields | — |
| Ad click IDs | fbclid, gclid, msclkid, ttclid | Facebook, Google, Microsoft, and TikTok click-ID fields | — |
| Web context | form_id, landing_page, referral_url, session_id | Web form ID, landing page, referral URL, session ID | — |
You don't have to send all 21 — send the ones your form has. The Web data source keeps this group of mappings together, so a different form family can use its own data source with a different set of keys without any overlap.
When something fails: the Async Log
Because a record is built a moment after your form gets its success reply, the place to confirm what actually happened is the Async Log — REDA's record of background processing. When a submission can't be turned into a record — a required field missing, a value that fails a rule — REDA rolls the write back and writes an Async Log entry instead. Nothing is silently dropped.
Each entry for a failed submission carries the source it came from, a failed count, and — most useful of all — the full request in its details, so you can see exactly what the form sent and why it was rejected. To fix a bad submission, correct the form (or the data) and submit it again; there's no automatic retry. For the anatomy of the log itself, the Attention Needed flag, and the admin email alerts, see Understanding REDA Async Logs.
Worked example: a campaign landing page
Meridian Properties runs a summer-leasing landing page. When a prospect submits the contact form, the page sends this request to .../dataservice/reda1__Inquiry__c/Web with an x-api-key header carrying Meridian's key:
[
{"key": "FirstName", "value": "Aisha"},
{"key": "LastName", "value": "Rahman"},
{"key": "Email", "value": "aisha@example.com"},
{"key": "utm_source", "value": "google"},
{"key": "utm_campaign", "value": "summer-lease"},
{"key": "gclid", "value": "..."}
]
REDA replies 200 {"success": true}, and moments later an Inquiry named Aisha Rahman appears — Inquiry Source Web, with the campaign and Google click ID recorded for marketing's reports.
Updating instead. If Aisha later resubmits with her phone number, the same request plus {"key": "recordId", "value": "<her inquiry's id>"} updates her existing inquiry rather than creating a duplicate.
When it fails. If a submission arrives with a required field missing, no record is created — but an Async Log entry appears carrying the full payload, so you can see what was sent and correct the form.
Where to go next
- Adding Data Service Objects & Sources — wire the same engine to a new record type or split forms into separate sources.
- Web Inquiries & Tour Requests — the sibling capture path, where your REDA listing pages write inquiries directly.
- Understanding REDA Async Logs — the full anatomy of the failure log this article points you to.
- Reading REDA Data via Salesforce APIs — the outbound, read-and-write side by contrast.
- Finding & Merging Duplicate Inquiries — clean up when the same prospect submits twice.
Frequently asked questions
The record type's Setup row has an auth key set, and the key your request sends in the x-api-key header doesn't match it. Confirm your form is sending the current key.
A success reply means your request was accepted, not that the record was written — those are two separate steps. Check the Async Log for the processing failure and the payload that caused it.
You asked for an operation the Setup row doesn't allow — sending a recordId (an update) without Edit Record switched on, or creating a record without Create Record switched on. Enable the matching switch on the Setup row.
Yes. Each data source segment in the address keeps its own group of mappings, so several forms can feed the same record type with different key sets. See Adding Data Service Objects & Sources.
No. The demo key is an environment-specific value meant only for trials. Set your own key on each record type's Setup row and rotate it immediately if it's ever exposed.
Was this article helpful?