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.

Query and multipart values

Query parameter values in params and text fields in formData accept strings, numbers, and booleans. The HTTP runtime converts numbers and booleans to text before request validation and sending: true becomes 'true', false becomes 'false', and 0 becomes '0'. This conversion preserves the original request object. For example, { key: 'skip', value: 1 } and { key: 'active', value: true } are valid query parameters. Query values must be nonempty; multipart text fields may contain an empty string. The legacy plain query-map type retains its historical '[object Object]' wire conversion; serialize structured queries explicitly with JSON.stringify. Arrays and nested query maps are unsupported, and multipart text values cannot be objects.

Payload ownership and diagnostics

Request and response bodies are integration-owned content. Explicit Vault reads produce ordinary values in the caller. HTTP preserves JSON, text and binary body content. response.data retains the provider body, including any credential echo. Decide what to return, persist or log in your own code. Provider headers can also echo credentials; choose safe response fields. Vault reads omit credential values from automatic previews. Ordinary HTTP calls use bounded previews; keep credential-bearing payloads out of execution captures. Transport failures retain safe error codes, HTTP status and retry metadata without exposing Axios request objects or credential-bearing URLs. HTTP data, multipart text and webhook JSON bodies do not consume the DTO control-field byte budget. Runtime tests cover 60 MiB payloads; component memory, deadlines, proxy and provider limits still govern actual delivery. For queued webhooks, saveDetails and maskDetails control a separate history snapshot. For explicitly read credentials, configure maskDetails for credential-bearing request sections before saving webhook history. History masking does not change delivery content.

Call a JSON API

Keep credentials in Vault and send query parameters through params. Read the value explicitly with await vault.get or await vault.getAccessToken, then build the outgoing header. Protect execution capture and never log credentials. Provider bodies can echo credentials; return only the fields your caller needs.
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. vault.get defaults to instance scope. Personal reads in saved Components require the exact grant and a verified executing owner; direct owner reads use the current account. Integration consumption follows the same saved Component or Tool grant mapping:
The grant follows the consumer’s stable identity across updates; review changed code before running it with credentials. Values are ordinary strings or Buffers in code. Reuse a read for a stable execution snapshot; read again when the latest value is required. Queue credential names rather than tokens.

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() sends real external requests in either execution mode. readOnly: true rejects a Storage response target and protected Platform API writes before transport; it does not simulate third-party side effects.
  • 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.
  • Proxy mode supports JSON/text requests, text/binary responses and both Storage transfer directions. Use requestType: 'storage' with source to send a file, and responseType: 'storage' with target to save a response. They may be combined for conversion.
  • With proxy: true, Go calls the provider through the dedicated egress network used for IP allowlisting. It streams the Storage source and sends the response directly to the authorized Storage upload URL. File bytes stay in Go; runtime prepares or claims the target session, verifies the upload receipt against Storage metadata, then finalizes.
  • Only complete 2xx responses are saved. Other statuses abort the unused target session and return bounded diagnostic text. Interrupted source reads and uploads fail without replaying the provider request. A lost upload acknowledgement may be reconciled from a complete receipt, without repeating the provider call.
  • Proxy mode does not expose live byte/SSE iterators, multipart uploads, document responses or current-caller credentials.
  • Explicit text responses retain the provider’s text even when its content type is JSON. Buffer/base64 responses preserve binary data. Set-Cookie retains every value as an array.
  • Destination parameters and credentials stay within the destination request. HTTP errors return a status to inspect; proxy transport and incomplete-response failures throw.
  • 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 October 14, 2026