Third-Party Integrations
By the end your blueprint can call an external API, receive its webhooks, keep data in sync and survive failures, with the credentials off the canvas.
Outbound: your blueprint calls their API
Credentials first
When the service has a provider type, configure a service provider and name it on the block: the key stays on the cluster and never enters the run. For anything else, store the key as a secure system setting (e.g.
stripe_secret_key) and read it withvalue_get_system_key_select(get setting). Never in the blueprint. See custom keys.Build the request
Use the request blocks:
function_trigger_webhook_http_get_json(Request: GET JSON),function_trigger_webhook_http_post(Request: POST json) and their siblings in the webhooks group. Set theurl, theheadersorauthfrom the setting, and abodyfromobject_new_fields(new object).Parse the response
Map only the fields you need from
responseinto your documents withobject_update_fields(update existing object). Do not mirror their whole payload.Handle failure explicitly
Branch on the
codepin: log, retry via the queue for transient errors (429, 5xx), and take an alert path for permanent ones. See error handling.
Inbound: their service calls yours
Register an endpoint
on_startup_register_uri_post(on api post) gives you a public webhook URL:https://<cluster>/api/v1/<uri>.Verify the sender
A shared-secret signature header, an HMAC check or an unguessable URI segment. Treat every unverified payload as hostile.
Reply fast
Answer 200 with a small ack, then do the real work in the queue. Otherwise senders time out and retry, which gives you duplicate events.
Deduplicate
Store received event ids and skip the ones you have seen, because webhooks retry.
Keeping data in sync needs one system of record
- Pull:
schedule_repeating_event(repeating event) polls their list endpoint on an interval and upserts by external id withfunction_upsert_document_from_mutations(upsert document). See Storages. - Push: react to local changes with storage events and forward them to the service.
- Conflict rule: pick one system of record per field and write it down in the flow's comments. Two-way sync without it always corrupts something.
Rules that keep an integration alive
- Rotate credentials by editing the service provider or the system setting. Every flow picks it up on its next run, with no blueprint edits.
- Log every outbound call (endpoint, status, duration) during rollout; sample it later.
- Respect their rate limits with queue debounce instead of bursts.
- Build a tiny health check: a scheduled call that verifies the token still works, and alerts via your own email flow (Email System Setup).
Next steps
Integrations Every service with blocks of its own. Remote Access Control Securing the webhooks you expose. Queue Retries, debounce, and background sync work. Common Blueprint Patterns Auth and error-handling recipes for your calls.Frequently asked
How do I call an external API from a RUAL blueprint?
Store the API key as a secure system setting and read it with get system setting, build the request with the http request blocks, and map only the fields you need into your documents. Search the block library for the service name first: postmark, mailchimp, discord and twilio have ready-made block groups.
How do I receive webhooks in RUAL?
Register an endpoint with on_startup_register_uri_post, verify the sender with a signature header, HMAC check or unguessable URI segment, reply fast with a small 200 ack, and do the real work in the queue. Deduplicate by event id, because senders time out and retry.
How do I keep RUAL data in sync with an external service?
Pull with a schedule_repeating_event that polls their list endpoint and upserts by external id, and push by reacting to local changes with storage events. Pick one system of record per field and write it down, because two-way sync without that rule always corrupts something.