Skip to content
Helix Docs

Connect an API that isn't listed

Connect an API that isn't in the supported services list with a generic service, from bearer token to OAuth 2.0 client credentials, OAuth 1.0a, HMAC, or AWS.

For developers Updated Oct 6, 2026
View as Markdown

If the API you need isn’t in the supported services list, connect it with one of seven generic services: HTTP Bearer Token, HTTP Basic Authentication, Custom Token Authentication, HTTP OAuth 2.0 Bearer, HTTP OAuth 1.0a, HTTP HMAC signature, or HTTP AWS Signature v4. You enter the credential once in the dashboard, and your function calls the API with ctx.http.authed('alias') like any other connected service. The platform adds the credential to the request, so the secret never reaches your code.

This page walks through the whole path with a made-up credential against a public test API, so you can run it without a third-party account.

Pick a generic service

If the API expectsPick
Authorization: Bearer <token>HTTP Bearer Token
A username and password, or an API token used as the passwordHTTP Basic Authentication
A token or API key in a header you name, or in the query stringCustom Token Authentication
An OAuth 2.0 token from a client ID and client secret (the client credentials grant)HTTP OAuth 2.0 Bearer
An OAuth 1.0a signed requestHTTP OAuth 1.0a
A signature computed over the request, such as X-Signature: ...HTTP HMAC signature
An AWS Signature v4 signed requestHTTP AWS Signature v4

HTTP OAuth 2.0 Bearer covers only the client credentials grant, where your server exchanges a client ID and secret for a token and Helix refreshes it for you. OAuth 2.0 with a user sign-in is not a generic service. If the service offers it, use its own entry in the supported services list, which handles sign-in and refresh.

What to enter in the form

ServiceFields
HTTP Bearer TokenToken
HTTP Basic AuthenticationUsername, Password
Custom Token AuthenticationToken, Location, Location Value, Pin to domain (optional)
HTTP OAuth 2.0 BearerClient ID, Client Secret, Token URL. See OAuth 2.0 client credentials below
HTTP OAuth 1.0a, HTTP HMAC signature, HTTP AWS Signature v4Described in signed requests below

For Custom Token Authentication:

FieldValue
TokenThe API key or token
Locationheader (the default) or query for the query string
Location ValueThe header name, such as X-Api-Key, or the query parameter name, such as api_key
Pin to domainOptional, and recommended. The only domain this credential may be used with, such as api.vendor.com. Subdomains are included. Enter the bare domain: no https://, path, wildcard, or port

OAuth 2.0 client credentials

HTTP OAuth 2.0 Bearer is for APIs that issue tokens from a client ID and client secret. You enter the credentials and the token URL once. Helix requests the token, stores it, refreshes it when it expires, and sends Authorization: Bearer <token> on every call.

FieldValue
Client IDThe client ID the API issued to you
Client SecretThe client secret the API issued to you
Token URLThe full URL of the token endpoint, such as https://login.vendor.com/oauth2/token

The token URL does not have to be on the same host as the API. If tokens come from login.vendor.com and you call api.vendor.com, enter the token URL as above and pass the API URL in your code as usual.

When you create the authentication you also choose how the API expects the client to identify itself at the token endpoint:

ChoicePick it when the API expects
Client credentials (credentials in request body), the defaultThe client ID and secret as form fields in the token request
Client credentials (HTTP Basic client authentication)The client ID and secret in an Authorization: Basic header on the token request

Your API’s documentation says which. If one is refused, the other is the one to try.

Two limits to know:

  • No domain restriction. Unlike the signed services below, this credential is not limited to one domain, so it is sent to whatever host your code calls with this alias. Use an alias only for the API you connected it to.
  • No scope field. The token is requested without a scope. If the API requires one, this service can’t connect it yet.

Any other header the API needs, such as a profile or tenant header, is set by your code on the request. Helix only adds the Authorization header.

Signed requests

OAuth 1.0a, HMAC, and AWS Signature v4 sign each request instead of sending a fixed token. You enter the secrets once, and the platform computes the signature on every call.

Pin to domain is required

A signed credential can only be used against the domain you pin it to, and its subdomains. api.vendor.com allows eu.api.vendor.com, not vendor.com. A request to any other host fails instead of sending the credential. Enter the bare domain: no https://, path, wildcard, or port.

These services also refuse to send a request when a required value is missing.

HTTP OAuth 1.0a

FieldValue
Consumer keyThe key issued to your application
Consumer secretThe secret issued to your application
TokenOptional. Leave Token and Token secret empty for two-legged OAuth
Token secretOptional, as above
Signature methodHMAC-SHA1 (the default) or HMAC-SHA256
Pin to domainRequired

You supply the credentials. Helix signs each request with them but doesn’t run the OAuth 1.0a token exchange, so for an API that needs a user’s access token you must already hold the token and token secret.

Not supported:

  • The realm parameter
  • The RSA-SHA1 and PLAINTEXT signature methods
  • Requests with a form-urlencoded body

HTTP HMAC signature

FieldValue
SecretThe shared secret the API verifies against
Algorithmsha1, sha256 (the default), or sha512
Signature encodinghex (the default) or base64
Header nameThe header that carries the signature, such as X-Signature
Signature formatThe header value, which must contain {{signature}}, such as sha256={{signature}}
Sign the request bodytrue (the default) or false
Signed headersOptional, comma-separated, in order. Your function sets these headers on the request
Pin to domainRequired

The signature covers the exact bytes your function sends. If the API verifies a re-serialized version of the body, the signatures won’t match. Sign the body, or list at least one signed header.

HTTP AWS Signature v4

FieldValue
Access keyThe AWS access key ID
Secret keyThe AWS secret access key
Session tokenOptional, for temporary credentials
Signing service nameOptional. Only needed when the host doesn’t name the service
RegionOptional. Only needed when the host doesn’t name the region
Pin to domainRequired, and prefilled with amazonaws.com

The region and service come from a regional host such as sts.us-east-1.amazonaws.com. Set them yourself when the host doesn’t name them, or names a different service than the one that signs. For example, bedrock-runtime signs as bedrock.

Worked example

This example uses httpbin.org, a public API that echoes back what it receives. The token below is made up. Don’t enter a real secret while you try this.

1. Create the authentication

helix auth connect --new

The command opens the dashboard’s connect page for your workspace. Add --no-open to print the link instead. In the dashboard, choose HTTP Bearer Token, enter demo-token-123 as the token, and name the authentication.

Back in the terminal, the CLI finds the new authentication and writes an alias into helix.config.ts. The CLI suggests an alias from the service name, so here it is http_bearer_token. You can type a different one at the prompt, using lowercase letters, digits, and underscores, starting with a letter. Without a terminal, such as in an agent loop, the command only prints the link. Once you’ve created the authentication, wire it up with helix auth connect or helix auth add <alias> <uuid>.

2. Call the API

// functions/api/v1/demo.get.ts
import { defineFunction } from '@trayai/helix-sdk';

export default defineFunction(async (ctx) => {
  const res = await ctx.http
    .authed('http_bearer_token')
    .get('https://httpbin.org/bearer');

  return res.body;
});

An authed call returns { status, body, headers }. body is already parsed JSON for a JSON response. A non-2xx answer from the API is returned, not thrown, so check res.status when you need to handle errors.

3. Run it

helix dev
curl http://localhost:3000/api/v1/demo

Success looks like this:

{ "authenticated": true, "token": "demo-token-123" }

The test API received Authorization: Bearer demo-token-123, which your function never wrote.

Try the other two

The same steps work with the other generic services. Change the alias and the URL in step 2, and return res.body as before.

ServiceEntered in the formCallResponse shows
HTTP Basic AuthenticationUsername tester, password s3cret-passhttps://httpbin.org/basic-auth/tester/s3cret-pass{"authenticated": true, "user": "tester"}
Custom Token AuthenticationLocation query, Location Value api_keyhttps://httpbin.org/anythingargs contains api_key with your token
Custom Token AuthenticationLocation header, Location Value X-Api-Keyhttps://httpbin.org/headersThe X-Api-Key header with your token

Try the signed services

Each example uses a public test API and made-up or published test keys, so you need no real account. Create the authentication as in step 1 above. The aliases below are the CLI’s suggested defaults (http_oauth1, http_hmac, http_aws_sigv4), and you can edit them at the prompt. Call each from a function that returns the result:

// functions/api/v1/signed.get.ts
import { defineFunction } from '@trayai/helix-sdk';

export default defineFunction(async (ctx) => {
  const res = await ctx.http.authed('http_oauth1').get('https://postman-echo.com/oauth1');
  return { status: res.status, body: res.body };
});

OAuth 1.0a

Postman Echo checks the signature with its published test key.

FieldValue
Consumer keyRKCGzna7bv9YD57c
Consumer secretD+EdQ-gs$-%@2Nu7
Token and Token secretLeave empty
Signature methodHMAC-SHA1
Pin to domainpostman-echo.com

Call GET https://postman-echo.com/oauth1. Success is status 200 with this body:

{ "status": "pass", "message": "OAuth-1.0a signature verification was successful" }

HMAC signature

FieldValue
Secretdummy-hmac-secret
Algorithmsha256
Signature encodinghex
Header nameX-Signature
Signature format{{signature}}
Sign the request bodytrue
Signed headersLeave empty
Pin to domainhttpbin.org

Send a JSON body to the echo endpoint:

const res = await ctx.http
  .authed('http_hmac')
  .post('https://httpbin.org/anything', { body: { event: 'order.created', id: 42 } });

The echo shows the exact string sent in body.data and the signature in body.headers['X-Signature']. For this body and secret the signature is eec200cc0004a0c3ceb9aeb1a4ddea237a549f1f65a11c40352347cbfdc394b4. Check it yourself:

printf '%s' '{"event":"order.created","id":42}' | openssl dgst -sha256 -hmac 'dummy-hmac-secret'

AWS Signature v4

FieldValue
Access keyAKIDEXAMPLE
Secret keywJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY
Session tokenLeave empty
Pin to domainamazonaws.com

These are the example keys from AWS’s own documentation, so AWS rejects them. Call GET https://sts.us-east-1.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15. Success for this exercise is status 403 with <Code>InvalidClientTokenId</Code> in the body. That shows AWS parsed a correctly formed signed request and rejected only the key. An unsigned request returns MissingAuthenticationToken instead. This does not prove the signature is valid, only that it is well formed. With a real key, the same call returns your account details.

Troubleshooting

The API answers 401. The call doesn’t throw: the 401 comes back as res.status === 401. The values or the location are wrong. Check the Token, Location, and Location Value you entered against what the API’s documentation asks for.

You want to see what is sent. Point a made-up credential at an echo endpoint such as https://httpbin.org/anything. Never do this with a real secret, because the echo site would receive it.

An OAuth 2.0 authentication won’t connect or the API answers 401. Check the Token URL first: it must be the token endpoint, not the API’s base URL. Then try the other client authentication choice in the table above. The credentials are sent to the token URL you entered, so a typo there can also leak the client secret to the wrong host. Re-enter the authentication if you suspect it.

A signed request is refused. HTTP OAuth 1.0a, HTTP HMAC signature, and HTTP AWS Signature v4 send nothing when a required value is missing or the host is outside the pinned domain. Check the form values and the Pin to domain against the URL you call.

A missing alias error. The alias isn’t in helix.config.ts. The error lists the aliases that are configured, so compare it with the name your code uses.

For how aliases, refresh, and request logging work, see connected services.

Loading search…

Jump to a section

tab to move · esc to close