REST / HTTP Request¶
Audience: Everyone / Developers · Tags:
rest,http,connector
The generic connector: make an HTTP request to any public API as a flow
action. Use it to call an app that doesn't have a dedicated connector yet.
connectorKey is rest_sdk, action type request, authType is none —
nothing to install or authorize, it's always available in every workspace.
Fields¶
| Field | Required | Type | Notes |
|---|---|---|---|
url |
Yes | string | Must be http:// or https://. Must resolve to a public address (see SSRF rule below). |
method |
No | string | e.g. GET, POST, PUT, PATCH, DELETE. Defaults to GET. |
headers |
No | object | Header name/value pairs, e.g. {"Authorization": "Bearer …"}. |
body |
No | string | Sent as-is. If you pass an object instead of a string, SnapLink JSON-encodes it for you. |
Output: { status, body } — the HTTP status code, and the response body
(parsed as JSON when possible, otherwise the raw text). Headers and any
secrets you passed are never logged or echoed back.
The SSRF rule¶
SnapLink won't send requests to private network addresses — only real, public
web addresses. Concretely: no localhost, no 127.0.0.1, no 10.x.x.x /
172.16-31.x.x / 192.168.x.x, no link-local addresses, and every hop of a
redirect is checked the same way (a redirect can't sneak you onto an internal
address). This protects your infrastructure and SnapLink's — it's not
something you can turn off from the flow editor. A blocked destination fails
with error code blocked.
Worked example¶
This flow: webhook trigger → REST action that posts to
postman-echo.com, which always echoes back
whatever you send — a good way to see a REST action work with zero setup. (For
a URL you can watch in real time in a browser, use
webhook.site instead: generate a unique URL there and
use it as url below.)
1. Flow definition (create the flow, then this as the draft):
{
"trigger": { "key": "t", "connectorKey": "webhook", "triggerType": "webhook" },
"actions": [
{
"key": "a1",
"connectorKey": "rest_sdk",
"actionType": "request",
"input": {
"url": "https://postman-echo.com/post",
"method": "POST",
"headers": { "Content-Type": "application/json" },
"body": "{\"event\":\"lead.created\"}"
}
}
]
}
curl -X POST "https://api.snaplink.cloudsolutionaccelerators.com/api/v1/flows/flow_abc123/drafts" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"definition": { "trigger": {"key":"t","connectorKey":"webhook","triggerType":"webhook"}, "actions": [{"key":"a1","connectorKey":"rest_sdk","actionType":"request","input":{"url":"https://postman-echo.com/post","method":"POST","headers":{"Content-Type":"application/json"},"body":"{\"event\":\"lead.created\"}"}}] }}'
2. Promote the draft to activate it:
curl -X POST "https://api.snaplink.cloudsolutionaccelerators.com/api/v1/drafts/draft_xyz/promote" \
-H "Authorization: Bearer $TOKEN"
3. Trigger it (get the webhook URL first — see webhook.md):
curl -X POST "https://api.snaplink.cloudsolutionaccelerators.com/api/v1/webhooks/flow_abc123/<secret>" \
-H "Content-Type: application/json" -d '{}'
{ "ok": true, "data": { "runId": "run_01HF...", "status": "queued" } }
4. Check the result in Execution History.
The run's action step shows status: 200 and postman-echo's response body
(which just echoes your request back) as output.body.
Important: the body above is fixed text you write once when building the
flow. SnapLink doesn't insert data from the incoming webhook request into it —
every run sends exactly the same body, regardless of what triggered it.
Error codes¶
| Code | Meaning |
|---|---|
blocked |
Destination is private/internal — SSRF protection. Use a public https URL. |
auth |
Target returned 401/403. |
bad_request |
Target returned another 4xx. |
upstream_5xx |
Target returned 5xx. |
timeout |
The target didn't respond in time. |
rate_limit |
Target returned 429. |
Limitations¶
- Requests to non-public addresses are always blocked in production — there's no per-workspace allowlist today.
- No response streaming; the whole response is read before the action completes.
- The action config carries auth for the target API (put a token in
headers) — the REST connector itself has no credential of its own.
If something goes wrong¶
Start with the error code on the failed step —
Connector failed maps each code to a
fix. blocked almost always means the URL points at a private/internal
address; auth/bad_request means fix the target's expected headers or body.
Related: Webhook trigger · Connector Catalog · Execution failures