Making API Requests
Once you have obtained role credentials by assuming your business unit's IAM role, every HTTP request to a Bifrost API is authenticated using AWS Signature Version 4 (SigV4).
Instead of sending a static token in a header, SigV4 computes a cryptographic signature over the HTTP method, URL, headers, payload, and timestamp using your assumed role's credentials. When the request arrives, API Gateway verifies the signature and checks whether the role you assumed is allowed to perform that operation (see Permission Levels). All available endpoints, base URLs, and request schemas are documented in the API Reference.
Signing requests
Every HTTP request must be signed with SigV4 using region eu-west-1 and service name execute-api. Because you are authenticating with temporary role credentials, the request must include both the computed Authorization header and the X-Amz-Security-Token header.
Whether you resolve credentials using an AWS config profile or at runtime in application code, pass that credentials object to an AWS-maintained signer rather than implementing SigV4 calculation by hand:
- cURL
- Python
- TypeScript
# Using credentials exported in your shell
# (or via: eval "$(aws configure export-credentials --profile bifrost --format env)")
curl --request GET \
--url "https://bifrost-prod.carrier.io/device-api/v1/devices?limit=25" \
--aws-sigv4 "aws:amz:eu-west-1:execute-api" \
--user "$AWS_ACCESS_KEY_ID:$AWS_SECRET_ACCESS_KEY" \
-H "X-Amz-Security-Token: $AWS_SESSION_TOKEN"
import requests
from botocore.auth import SigV4Auth
from botocore.awsrequest import AWSRequest
# Pass the credentials object obtained in Authenticating
# (via config profile or runtime session)
request = AWSRequest(
method="GET",
url="https://bifrost-prod.carrier.io/device-api/v1/devices",
params={"limit": "25"},
)
SigV4Auth(credentials.get_frozen_credentials(), "execute-api", "eu-west-1").add_auth(request)
prepared = request.prepare()
response = requests.get(prepared.url, headers=dict(prepared.headers))
response.raise_for_status()
import { Sha256 } from "@aws-crypto/sha256-js";
import { HttpRequest } from "@smithy/protocol-http";
import { SignatureV4 } from "@smithy/signature-v4";
const url = new URL("https://bifrost-prod.carrier.io/device-api/v1/devices?limit=25");
// Pass the credentials provider obtained in Authenticating
// (fromIni or fromTemporaryCredentials)
const signer = new SignatureV4({
service: "execute-api",
region: "eu-west-1",
sha256: Sha256,
credentials,
});
const signed = await signer.sign(
new HttpRequest({
method: "GET",
protocol: url.protocol,
hostname: url.hostname,
path: url.pathname,
query: { limit: "25" },
headers: { host: url.hostname },
}),
);
const response = await fetch(url, {
method: signed.method,
headers: signed.headers,
});
Every operation in the API Reference also includes a ready-to-run cURL (SigV4) snippet for that specific endpoint.
Common errors
When a request fails during authentication, signing, or authorization, you will typically encounter one of these errors:
MissingAuthenticationTokenException(403 Forbidden): Returned by API Gateway in two different situations:- The request was sent without an
Authorizationheader. - You called a URL path or HTTP method that does not exist on the gateway (for example, omitting
/device-apifrom the path).
- The request was sent without an
InvalidSignatureException(403 Forbidden): The signature on the request did not match what API Gateway calculated. Check that your signer is configured with serviceexecute-apiand regioneu-west-1, that query string parameters and thehostheader were included in the signed request, and that the body or headers were not modified after signing.The security token included in the request is invalidorExpiredTokenException(403 Forbidden): Either you signed the request without passing the matchingX-Amz-Security-Tokenheader (for example, incurl), or exported session credentials have expired and need to be refreshed.User: arn:aws:sts::... is not authorized to perform: execute-api:Invoke(403 Forbidden): Your request signature is valid, but the role you assumed does not have the required permission level for that endpoint (for example, attempting to register or update a device while authenticated with a viewer role). Check the Operations matrix to verify which role is needed.TooManyRequestsException(429 Too Many Requests): Your client exceeded the API Gateway request rate or burst limit. Retry the request with exponential backoff.- Application and validation errors (
400,404,409,500): Once API Gateway accepts your signature and forwards the call, the service returns structured errors in the shape{ "message": string, "details"?: object }. Specific error responses for each operation are documented in the API Reference.