Skip to main content
Use api.httpCall() for an outbound request that belongs to the current Component execution. It supports ordinary JSON and text responses, binary payloads, multipart forms, live byte or SSE iterators, and direct transfers between HTTP and Storage. Inbound HTTP is a different boundary. Publish an Endpoint when another system must call RevoEngine; use a durable outbound Webhook when RevoEngine should deliver a retried notification without holding the current execution open.

Choose the right HTTP boundary

api.httpCall() is outbound and synchronous with the current execution. It does not publish an inbound route, create a durable retry queue, or prove that a successful remote response completed the provider’s business operation.

Request and response formats

Request and response formats are independent: JSON is the default. Set formats explicitly when they are part of the integration contract. requestType: 'json' is valid for every supported method, including bodyless requests; non-JSON request types require a method that accepts a body.

Call a JSON API

Keep credentials in Secrets and send query parameters through params rather than string concatenation.
Do not return the upstream error body blindly. It can contain credentials, personal data, or implementation details. Map expected failures to your own bounded response and keep safe correlation identifiers for investigation.

Make external mutations retry-safe

A timeout is ambiguous: the provider may have committed the operation before the connection failed. Generate or load a stable business idempotency key before the first attempt and reuse it for every retry.
Use a Job when the operation needs durable retry, reconciliation, or a longer execution budget. HTTP transport retry and business retry are different decisions.

Submit multipart form data

Put formData on the first request argument. For one Storage-backed binary part, leave that part’s value empty and provide source in options.
Reference each Storage entry directly when the request contains several files:
The runtime creates the MIME boundary. Do not set a manual multipart Content-Type header without the matching generated boundary.

Consume a byte stream

Live response iterators are available inside the local low-code V8 runtime. The initial await resolves after response headers; each iterator step then waits for data, EOF, or an error with backpressure.
Chunks are transport fragments, not application records or multipart boundaries. The runtime limits concurrent streams, chunk size, buffered data, and total execution time. Closing, breaking iteration, cancellation, failure, or Component completion releases the upstream request. Use a Storage target instead when the goal is to retain the complete response. It avoids exposing transport chunks to application code.

Consume Server-Sent Events

Set streamFormat: 'sse' for an upstream text/event-stream response.
Each item has { event, data, id? }. data remains a string; JSON and provider markers such as [DONE] are application data and must be interpreted explicitly. Reconnect and Last-Event-ID replay are not automatic. Incomplete frames at EOF are discarded.
Live byte and SSE iterators are local-runtime capabilities. They cannot be returned through remote JSON SDK calls or Custom Node.js, and they are unavailable with proxy mode. This does not add inbound SSE to RevoEngine Endpoints.

Stream HTTP responses into Storage

Use responseType: 'storage' with a flat target to keep a large response without buffering it in the Component.
Only successful 2xx bodies are stored. The runtime creates a direct upload session, streams the response, and finalizes it before returning response.storage.entry; response.data is then undefined. Failed writes abort the new session, while a failed replacement keeps the existing entry. The inverse direction uses requestType: 'storage' and source:
source and target can be combined for an external conversion API. A target may also fill and finalize an existing active, empty, direct upload session. For caller-controlled parts, incremental generation, repair, schema policy, or resumable upload behavior, use Storage upload sessions instead.

Receive callbacks and events

api.httpCall() does not receive traffic. Configure an authenticated Endpoint with a request guard, then read the validated request context from api.input() inside its Component.
The Endpoint input root contains body, query, headers, and parameters; operator-owned template values remain separate. Treat every caller field as untrusted, do not forward inbound headers wholesale, and deduplicate external event IDs before performing a business mutation. If the sender signs raw bytes, do not reconstruct the signature input from parsed JSON unless its protocol defines canonical JSON. Use an Event after acceptance when several Jobs or Agents should react independently. Use a Job directly when exactly one durable workflow owns the callback.

Runtime constraints

  • api.httpCall() is a no-op in debug mode and returns null; do not disable debug protection casually for a real external side effect.
  • One deadline covers request preparation, response headers, and the body. Receiving data does not reset it.
  • A Component cancellation or timeout does not recall a request already accepted by the remote service.
  • Storage and live-stream response modes cannot be combined with proxy mode.
  • Do not log signed URLs, authorization headers, Secret values, unrestricted request bodies, or provider error payloads.
See the generated api.httpCall() reference, Endpoints, Outbound webhooks, Events, and Storage.
Last modified on September 23, 2026