Skip to main content

REST API ExecModule

Overview

RestApiModule executes one bounded HTTP request from a ValkyrAI workflow. Version 2.0 replaces the legacy open-ended client contract with complete Workflow Studio metadata, destination-bound IntegrationAccount authentication, explicit write confirmation, bounded bodies and timeouts, safe read retries, single-attempt writes, disabled redirects, allowlisted response headers, sanitized target reporting, and credential-safe failures.

The canonical module identifier is:

com.valkyrlabs.workflow.modules.rest.RestApiModule

This direct HTTP client does not claim OpenAPI operation resolution, schema validation, browser cookies, streaming, multipart upload, automatic pagination, or automatic compensation. Use a provider-specific ExecModule when one exists; it can enforce a narrower resource and permission contract.

Usage

  1. Prefer a provider-specific ExecModule when ValkyrAI has one.
  2. For authenticated calls, create a least-privilege IntegrationAccount with status READY.
  3. Set IntegrationAccount.accountId to the exact allowed HTTPS base URL, including a path prefix when credentials should be limited below that path.
  4. Put the bearer/API key in apiKey or password; Basic authentication uses username and password.
  5. Configure method, url, authMode, expected statuses, timeout, and response bound.
  6. Set confirmWrite: true for POST, PUT, PATCH, or DELETE.
  7. After a write failure, reconcile provider state before manually retrying because delivery can be ambiguous.

Inputs

InputRequiredDescription
methodYesGET, HEAD, OPTIONS, POST, PUT, PATCH, or DELETE. Default: GET.
urlYesAbsolute HTTPS URL, or relative path resolved against a configured base URL. HTTP is accepted only for loopback testing.
bodyNoString or JSON-compatible body, serialized to at most 1 MiB UTF-8.
headersNoUp to 32 non-secret string headers; each value is capped at 4 KiB.
authModeNonone, bearer, api_key, or basic. Default: none.
confirmWriteFor writesMust be true for POST, PUT, PATCH, or DELETE.
idempotencyKeyNoOptional caller correlation key, capped at 256 bytes. A durable workflow provider key takes precedence.
expectedStatusNoUp to 32 accepted HTTP statuses. Default: 200, 201, 202, 204.
timeoutMsNoCall timeout from 1,000 through 60,000 ms. Default: 10,000.
maxResponseBytesNoResponse-body limit from 1 KiB through 5 MiB. Default: 1 MiB.
maxAttemptsNoRead-only attempt cap from 1 through 3. Writes always use one attempt.
parseJsonNoParse JSON content types and JSON-looking response bodies. Default: true.
responsePathNoDotted path selected from an object response after bounded JSON parsing.
failOnErrorNoThrow a generic sanitized exception after safe error output is recorded. Default: true.

Legacy configuration aliases endpoint, payload, retries, storeResponseAs, storeHeadersAs, lifecycleStage, and stageStatus remain available where they do not weaken the v2 safety contract. retries is interpreted as the bounded read-attempt cap; it never enables write retries.

Raw username, password, apiKey, api_key, accessToken, token, secret, authorization, cookie, and client-secret fields are rejected. Caller-provided Authorization, Proxy-Authorization, X-API-Key, cookie, host, content-length, transfer, upgrade, and other hop-by-hop headers are also rejected.

Outputs

OutputDescription
statussuccess or error.
methodNormalized HTTP method.
lastHttpStatusProvider HTTP status when a response was received.
lastHttpUrlSanitized scheme, host, port, and path. Query parameters and user information are never returned.
lastHttpDurationMsDuration of the final attempt.
attemptsNumber of HTTP attempts consumed.
restResponseBounded parsed or textual response body, or selected responsePath value.
responseHeadersAllowlisted bounded response headers such as content type, ETag, retry-after, request IDs, and idempotency receipt.
externalReceiptRefBounded provider idempotency receipt or response receipt identifier when available.
retryableWhether a read-only failure may be retried after checking the destination.
errorSafe object containing code, message, retryable, and optional httpStatus.

The legacy restError alias contains the same safe error object. Custom storeResponseAs and storeHeadersAs keys receive only the same bounded response and allowlisted header data.

IntegrationAccount Requirements

Authenticated requests require a bound IntegrationAccount with:

  • status exactly READY;
  • accountId containing the exact HTTPS base URL authorized to receive the credential;
  • a path prefix in accountId when access should be constrained below a provider subpath;
  • apiKey or password for bearer and api_key modes;
  • username and password for basic mode;
  • provider permissions limited to the resources and actions the workflow needs.

The requested URL must use the same scheme, host, and effective port as accountId, and its normalized path must remain within the bound path prefix. This prevents a workflow edit from redirecting the account credential to another origin or unrelated provider path.

authMode: none does not read IntegrationAccount secrets. Query-string credentials are unsupported in every mode.

Configuration

ConfigurationDefaultConstraint
authAccountNoneRequired and READY for authenticated calls.
authModenonenone, bearer, api_key, or basic.
methodGETSeven-method allowlist.
urlNoneRequired absolute HTTPS URL or relative path.
baseUrlRuntime defaultUsed only for relative unauthenticated calls; authenticated calls bind to IntegrationAccount.accountId.
headers{}Bounded non-secret string map.
bodyNoneAt most 1 MiB serialized.
confirmWritefalseRequired for every write method.
idempotencyKeyNoneOptional caller correlation key.
expectedStatus[200,201,202,204]Bounded list of statuses from 100 through 599.
parseJsontrueJSON parsing remains inside the response cap.
responsePathNoneOptional bounded dotted selector.
storeResponseAsNoneOptional safe, non-reserved output key.
storeHeadersAsNoneOptional safe, non-reserved output key.
timeoutMs100001,000–60,000 ms.
maxResponseBytes10485761,024–5,242,880 bytes.
maxAttempts11–3 for reads; fixed to one for writes.
failOnErrortrueException text contains only the normalized error code.

Operations

The module exposes one operation: issue one HTTP request.

Read-only methods are GET, HEAD, and OPTIONS. They may retry only network failures and statuses 429, 502, 503, and 504, never exceeding maxAttempts. Backoff is bounded and redirects remain disabled.

Write methods are POST, PUT, PATCH, and DELETE. They require confirmWrite: true and always use one transport attempt even when maxAttempts or legacy retries is greater than one. An Idempotency-Key helps provider-side reconciliation only when that provider supports it; it does not make every HTTP write intrinsically idempotent.

Request and response bodies are fully bounded. The client disables OkHttp connection-failure retries and both same-scheme and SSL redirects. Response headers are allowlisted; cookies and arbitrary provider headers never enter workflow state.

Errors and Failure Modes

CodeMeaningRecovery
VALIDATION_ERRORThe method, URL, credential placement, account binding, header, body, confirmation, timeout, response cap, or output key is invalid.Correct the named field. No unsafe request was sent.
HTTP_STATUS_ERRORThe provider returned a status outside expectedStatus.For reads, retry only when retryable is true. For writes, reconcile provider state before a manual retry.
NETWORK_ERRORConnection, TLS, timeout, or transport failed.Check the provider and account. Reconcile a write because delivery may be ambiguous.
RESPONSE_TOO_LARGEDeclared or streamed body exceeded maxResponseBytes.Narrow the provider response or raise the cap within 5 MiB. The oversized body is discarded.
RETRY_INTERRUPTEDA bounded read retry was interrupted.Preserve interruption and retry only after the workflow is healthy.
EXECUTION_ERRORAn unexpected local runtime failure occurred.Inspect sanitized runtime logs; do not assume the request was unsent.

Provider response error bodies and exception messages are not copied into failure output. Credential-bearing query parameters, headers, cookies, user information, and redirect targets are not reported.

Example

Create one order using a bearer credential stored in a destination-bound IntegrationAccount:

{
"method": "POST",
"url": "https://api.example.com/v1/orders",
"authMode": "bearer",
"confirmWrite": true,
"idempotencyKey": "order-ord-42",
"headers": {
"Accept": "application/json",
"Content-Type": "application/json"
},
"body": {
"orderId": "ord-42",
"total": 125.00,
"currency": "USD"
},
"expectedStatus": [201],
"timeoutMs": 10000,
"maxResponseBytes": 1048576,
"maxAttempts": 3,
"failOnError": false
}

Expected shape after one provider-confirmed request:

{
"status": "success",
"method": "POST",
"lastHttpStatus": 201,
"lastHttpUrl": "https://api.example.com/v1/orders",
"lastHttpDurationMs": 184,
"attempts": 1,
"retryable": false,
"restResponse": {
"id": "ord-42",
"state": "accepted"
},
"externalReceiptRef": "ord-42"
}

maxAttempts: 3 does not change the write behavior: the request still uses one attempt.

Notes

  • Pagination is provider-specific and not automatic. Model page or cursor inputs explicitly, then bound the workflow loop separately.
  • Rate limits surface as unexpected status 429. Read-only calls may use bounded attempts; writes remain single-attempt.
  • Idempotency depends on the provider honoring the selected key. Repeated workflow execution can still duplicate a side effect when the provider ignores it.
  • URL query values may be sent, but credential-like query parameter names are rejected and the query is removed from lastHttpUrl.
  • Relative authenticated URLs resolve against IntegrationAccount.accountId. Relative unauthenticated URLs use configured baseUrl or the runtime default.
  • HTTP is accepted only for loopback tests. Production destinations must use HTTPS.
  • The deterministic tests use a loopback HTTP server. They verify request construction, transient read retries, single-attempt writes, explicit confirmation, destination-bound bearer auth, raw-secret rejection, response caps, redirect refusal, secret-safe failures, annotation discovery, and metadata serialization. Live provider TLS, authentication, rate limits, and API-specific behavior remain deployment-time boundaries.