Outbound HTTP

Learn about Http.get / post / put / patch / delete to reach external services.

Http is the SDK’s HTTP client. Every outbound call must match an entry in permissions.http within backfill.config.ts (see configuration) or it’s blocked.

Signatures

interface RequestOpts {
  headers?: Record<string, string>;
  body?: any;
  auth?: {
    bearer?: string;
    basic?: { user: string; pass: string };
    oauth?: boolean | { minTtlSeconds?: number };
  };
  timeout?: number;
}

interface HttpResponse {
  status: number;
  headers: Record<string, string>;
  body: any;       // parsed JSON if the response is JSON; raw string otherwise
  ok: boolean;     // true if 2xx
}

Http.get(url, opts?)
Http.post(url, body?, opts?)
Http.put(url, body?, opts?)
Http.patch(url, body?, opts?)
Http.delete(url, opts?)

Permissions

Each entry in permissions.http is an https:// URL with an explicit host. Path wildcards are allowed; host wildcards are not.

permissions: {
  http: ["https://api.stripe.com/*"],
}

A request to a host not on the allowlist throws at runtime.

Making a request

const res = Http.get("https://api.stripe.com/v1/customers", {
  auth: { bearer: Secrets.get("stripe_api_key")! },
  timeout: 10_000,
});

if (!res.ok) {
  Log.error("Stripe call failed", { status: res.status, body: res.body });
  throw new Error("Stripe call failed");
}

const customers = res.body.data;

Authentication

Built-ins:

auth: { bearer: "sk_live_..." }                    // Authorization: Bearer ...
auth: { basic: { user: "key", pass: "secret" } }   // Authorization: Basic ...
auth: { oauth: true }                              // Connector OAuth bearer token
auth: { oauth: { minTtlSeconds: 300 } }            // Refresh first if needed

auth.oauth is available to connector routes whose manifest declares connection.oauth. See Connector OAuth.

For anything else, set the header directly:

Http.post(url, body, {
  headers: {
    "Authorization": "Bearer " + token,
    "X-Idempotency-Key": myKey,
  },
});

Bodies

body is auto-serialized:

  • A plain object → JSON, with Content-Type: application/json.
  • A string → sent as-is. Set Content-Type yourself.

The response body is parsed back to JSON when the server responds with a JSON content type, otherwise it’s a string.

Timeouts

timeout is in milliseconds. Default is platform-decided. For chatty external APIs, set it explicitly so a hung peer doesn’t block your hook.

Retries

Http does not retry. If you need retry-on-503 / retry-on-network-error semantics, write a small loop. For sync routes in connectors, retry behavior is yours.