Overview
An API relay is a server-side proxy that sits between your users and an external API, letting Curator call third-party services without exposing credentials to the browser. You configure the relay once; Curator then attaches your stored credentials, validates incoming calls, and forwards the assembled request to the external service on the caller’s behalf. The result: sensitive credentials never leave your server, your external API surface is limited to exactly what you expose, and you get a single, auditable integration point you can monitor, update, or disable without touching the calling code.When to use an API relay
API relays bridge Curator with any third-party API. Common scenarios:- Custom BI embeds from non-integrated platforms — a custom JavaScript embed that fetches live data from an external REST API, with the API key stored as a Curator constant instead of in the browser.
- Submitting form data to a webhook — Data Manager routes mark-commenting submissions to any HTTP endpoint, using an API relay as the connection point. See Sending Data to Webhooks.
- AI chat integration — let users talk to an AI assistant without exposing your paid AI account credentials.
Prerequisites
API relays require the Integration Automation feature to be enabled:- Log in to the Curator backend.
- Navigate to Settings > Portal Settings > Features.
- Enable Integration Automation under the Functionality section.
- Save and refresh the page.
Creating an API relay
- Navigate to Integrations > Automation > API Relay.
- Click New at the top of the list.
- Fill in the form (see the field reference below) and click Save.
- Once saved, the Link shown at the top of the edit form is the URL you will call to trigger the relay. Copy it and use it in your integration.
Security note: The Portal Link is publicly accessible by default — any caller who knows the URL can trigger the relay, and it is not tied to a logged-in user. If the relay exposes a sensitive upstream API, restrict access (see Securing a relay below).
Field reference
Basic settings
Outgoing Request URL
This section controls where Curator sends the relayed request.Outgoing Request Content
This section defines what Curator sends to the external API: the headers, fixed values, caller-supplied values, and body content.Headers
HTTP headers to attach to every outgoing request (e.g.Content-Type: application/json, Accept: application/json).
Each header entry has a Key, a Value, and an Allow Dynamic Values toggle. When dynamic values are enabled,
a caller can override that header’s value by sending an HTTP header of the same name in their request to the relay.
Constants
Fixed key-value pairs that are always sent with the outgoing request regardless of what the caller provides. This is the right place for credentials, API keys, tokens, or any other value that must remain server-side and must never be visible to the caller. Constants cannot be overridden by incoming requests.Variables
Named parameters that the caller is expected to supply at call time (e.g.start_date, region, user_id).
Each variable has a Key (the parameter name) and an Is Required? toggle. Required variables will cause
the relay to reject the call if they are missing. Variables are passed by the caller as query string parameters
or POST body fields using the same key name defined here.
Body Content
Static body content to include in the outgoing request (e.g. a fixed JSON or XML payload). Leave blank if the request body is built entirely from variables and constants. Body content applies to POST relays only — a GET relay sends its parameters on the URL and ignores the body. To let an incoming request set or edit the body at call time — whole-body replacement, placeholder substitution, or transforming the value before it is injected — enable Allow Dynamic Body Content. This is covered in full in Dynamic Body Content in the API Relay.Incoming Request Validation
Optional rules that Curator evaluates before forwarding any request. If a request fails validation, the relay is not called and Curator returns an error.Header-based validation
Define conditions on specific HTTP headers in the incoming request. For each rule, specify:- Header — the HTTP header name to inspect.
- Condition — one of: Matches, Does not match, Contains, Does not contain, Starts with, Ends with.
- Value — the value to test against.
Variable-based validation
The same conditional structure applied to query string or POST body parameters rather than headers.Validation failure response
By default, a validation failure returns an HTTP 403 response. Disable Should validation failures respond with error code? to return an HTTP 200 with an error message in the body instead. Some webhook endpoints or client-side integrations expect 200 for all responses; use this toggle if the caller cannot handle 4xx status codes.Securing a relay
The relay endpoint is public and unauthenticated — it does not require a logged-in user, and any caller who knows the Portal Link can trigger it. Your credentials stay safe (they live in Constants, server-side), but the endpoint itself is open. To lock it down:- Require a shared secret (recommended). Add an Incoming Request Validation rule that checks for a header
or variable only authorized callers know — e.g. a header
X-Relay-Tokenwith condition Matches and a long random value. Requests without it are rejected before the relay forwards anything. - Restrict by IP at the network layer. Curator has no built-in per-relay IP allowlist. To limit the relay to
specific source IPs, enforce it in front of Curator — in your web server (nginx/Apache), load balancer,
firewall, or WAF — by allowing only trusted IPs to reach the
/api/v1/integration/apiRelaypath. Do not rely on a validation rule against a forwarded header such asX-Forwarded-For: that header is caller-supplied and can be spoofed.
Calling the relay
Once a relay is saved, Curator generates a Portal Link shown at the top of the edit form. This is the URL you call to trigger the relay. Its structure is:api_relay_idis the numeric ID of the relay record (fixed).- Each configured Variable appears as a query parameter.
Response format
Curator returns a JSON object in all cases. The shape depends on whether the relay succeeded, failed, or was blocked by validation. On success:
On failure —
result is "Failure" and msg is a human-readable error. This covers both relay-level
problems (missing or invalid api_relay_id, a missing required variable) and upstream API errors: if the
external API responds with an HTTP status of 400 or higher, the relay reports failure with a message like
There was an error processing your request: API Relay call failed with HTTP code 500.
status instead of result) and return HTTP 403 by default (or
HTTP 200 if you have disabled the Should validation failures respond with error code? toggle).
Good to know
- Constants are never exposed to callers. They are stored server-side and merged into the outgoing request by Curator. A caller inspecting browser network traffic will only see the Curator relay URL and their own variables — not the upstream API credentials.
-
Variable names are pass-through. A variable named
start_datein the relay configuration must be sent asstart_datein the incoming request. Curator does not rename or transform variable names — only dynamic body content advanced processing can modify values. - Headers sent by the caller are not forwarded by default. Only headers you explicitly define in the Headers section are included in the outgoing request. This prevents accidental forwarding of cookies, session tokens, or other browser headers to the external API.
- Relay calls are unauthenticated by default. Curator does not require the caller to be a logged-in user to hit the relay endpoint — see Securing a relay if you need to restrict access.
-
Enabling Log Relay Usage adds full request/response logging. This is useful during development and
debugging but can be verbose. Logs are written to Curator’s standard application log files under
storage/logs/. Disable logging in production once the integration is confirmed working. -
The relay is a thin forwarder. It returns the upstream response body largely as-is (parsing it if it is
JSON) rather than reshaping it. The one thing it does act on is the upstream HTTP status: a 400-or-higher
response is turned into a
"Failure"envelope rather than passed through as a success.
Related
- Sending Data to Webhooks — how to connect an API relay to Data Manager for mark-commenting webhook submissions.
- Dynamic Body Content in the API Relay — letting an incoming request set or edit the outgoing request body.