Skip to content
This page View Markdown Open in ChatGPT Open in Claude

Request headers

Headers change how API Maker answers a call, without changing the URL. They work on every API : generated, schema, custom, system and third party. The response carries a few headers of its own, listed at the end.

All headers

Header Values What it does
x-am-authorization a token The API user : which application calls. Needed unless the API is public.
x-am-user-authorization a token The person, from a DB token generator.
x-aws-authorization, x-google-authorization, x-azure-authorization, x-custom-authorization a token The person, from AWS Cognito, Google, Azure AD or a custom provider.
x-am-response-case camelCase, snakeCase… The case of every key of the answer.
x-am-content-type-response application/json, text/xml, text/yaml… The format of the answer.
x-am-response-object-type no_action, make_flat Flatten nested objects.
x-am-meta true, false Execution time, plan, groups and sandbox in meta.
x-am-cache-control no_action, reset_cache Skip the cache for this call.
x-am-get-encrypted-data no_encryption, get_only_encryption, get_data_and_encryption Encrypt the answer.
x-am-encrypted-payload true The body is encrypted.
x-am-internationalization the name of a language The language of the messages.
x-am-tenant-username a tenant The tenant of a multi-tenant instance.
x-am-sandbox-timeout milliseconds How long the code of the call may run.
x-am-run-in-sandbox 0, 1, 2… Which sandboxes may run the code.
x-no-compression, accept-encoding true / br, gzip, deflate, identity Compression of the answer.

x-am-authorization

The token of an API user : the application calling. Its groups decide which APIs, tables and fields the call may reach. The token comes from the token API and expires after jwtOptions.expiresIn seconds (72 hours by default, expiresInSeconds in the token request changes it).

x-am-authorization: eyJhbGciOiJIUzI1NiIsInR1BydlRrblJlcS
  • Missing or invalid : 401. Valid but no group grants the API : 403.
  • Public APIs (apiAccessType: IS_PUBLIC in the settings) do not need it.
  • Read it in your code from g.req.auth.authAMUser.

x-am-user-authorization

The token of a person, a row of your own users table, made by a DB token generator (auth provider) through the token API. It is required when the settings of the database, the table, the API or the custom API list that provider in authProviders.

x-am-user-authorization: eyJhbGciOiJIpXVCJBydlRrblJlcS
  • Read it in your code from g.req.auth.authAMDB : the columns of the user selected by the generator, and the groups of the groups column.
  • A token made for a tenant works for that tenant only, see Multi-tenant.

x-aws-authorization

The access token of AWS Cognito, when an AWS auth provider is configured. Read from g.req.auth.authAWS.

x-aws-authorization: eyJhbGciOInR5cCI6IkpXVCJ9

x-google-authorization

The id token of a Google sign-in, when a Google auth provider is configured. Read from g.req.auth.authGoogle.

x-google-authorization: eyJhbGciOiJIUzI1I6IkpXVCJ9

x-azure-authorization

The token of Azure Active Directory, when an Azure auth provider is configured. Read from g.req.auth.authAzure.

x-azure-authorization: eyJhbGciOiJIUzI1NI6IkpXVCJ9

x-custom-authorization

The token of a custom auth provider : your own generator and validator code. What the validator returns is in g.req.auth.authCustom.

x-custom-authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

x-am-response-case

Changes the case of every key of the answer, nested objects and arrays included. Default : noChange.

Value first_name becomes
noChange first_name
camelCase firstName
capitalCase First Name
constantCase FIRST_NAME
dotCase first.name
headerCase First-Name
noCase first name
paramCase first-name
pascalCase FirstName
pathCase first/name
sentenceCase First name
snakeCase first_name

NoChange response

x-am-response-case: noChange

CamelCase response

x-am-response-case: camelCase
{ "firstName": "JOHN", "lastName": "DOE" }

CapitalCase response

{ "First Name": "JOHN", "Last Name": "DOE" }

ConstantCase response

{ "FIRST_NAME": "JOHN", "LAST_NAME": "DOE" }

DotCase response

{ "first.name": "JOHN", "last.name": "DOE" }

HeaderCase response

{ "First-Name": "JOHN", "Last-Name": "DOE" }

NoCase response

{ "first name": "JOHN", "last name": "DOE" }

ParamCase response

{ "first-name": "JOHN", "last-name": "DOE" }

PascalCase response

{ "FirstName": "JOHN", "LastName": "DOE" }

PathCase response

{ "first/name": "JOHN", "last/name": "DOE" }

SentenceCase response

{ "First name": "JOHN", "Last name": "DOE" }

SnakeCase response

{ "first_name": "JOHN", "last_name": "DOE" }

x-am-response-object-type

Flattens nested objects, such as the ones deep produces, into one level with _ between the names. Default : no_action.

No action

x-am-response-object-type: no_action
{ "id": 101, "state_id": { "id": 201, "country_id": { "id": 301, "country_name": "INDIA" }, "state_name": "GUJARAT" }, "city_name": "AHMEDABAD" }

Make flat

x-am-response-object-type: make_flat
{ "id": 101, "state_id_id": 201, "state_id_country_id_id": 301, "state_id_country_id_country_name": "INDIA", "state_id_state_name": "GUJARAT", "city_name": "AHMEDABAD" }
  • Handy for grids, CSV exports and spreadsheets.

x-am-meta

Adds meta to the answer. Default : false.

False

x-am-meta: false

True

x-am-meta: true
{
    "data": [ { "id": 301, "country_name": "INDIA" } ],
    "meta": {
        "executionTime": "15ms",
        "executionTimeMS": 15,
        "executionPlan": [],
        "apiAccessGroups": [ { "groupId": "6381b80359bdbd3a87c9abd5", "groupName": "all_permission", "hasAccess": true } ],
        "runBy": [ { "apiCategory": "CUSTOM_APIS", "serverId": "server1", "processId": "…", "workerId": "1", "port": 38246 } ]
    }
}
Key Meaning
executionTime, executionTimeMS Time spent in API Maker, without the network.
executionPlan The explain plan of MongoDB for the query.
apiAccessGroups The groups of the API user and which one granted the call.
runBy Which server, process, worker and sandbox ran the code.

x-am-internationalization

The name of a language of i18N Management. Every message of the answer, the messages of API Maker as well as your own from errorList and thrown strings, comes back in that language. The value Default (or no header) gives the original messages.

x-am-internationalization: Hindi
Default
{ "code": 400, "message": "Please provide id param value" }
Hindi
{ "code": 400, "message": "कृपया आईडी पैरामीटर का मान प्रदान करें." }
Chinese simple
{ "code": 400, "message": "请提供id参数的值" }
Spanish
{ "code": 400, "message": "Proporcione el valor del parámetro id." }
Japanese
{ "code": 400, "message": "id パラメータの値を入力してください" }
Urdu
{ "code": 400, "message": "براہ کرم id پیرامیٹر کی قدر فراہم کریں۔" }
  • Add a language, change a message, and the next call answers with it : no restart.

x-am-run-in-sandbox

Which of the sandboxes of the account may run the code of this call (custom API, hooks, events). An account has sandboxCountForAdmin sandboxes per API Maker process.

x-am-run-in-sandbox: 0      # any sandbox (default)
x-am-run-in-sandbox: 1      # always the first sandbox
x-am-run-in-sandbox: 2      # one of the first two
x-am-run-in-sandbox: 3      # one of the first three
  • Pin a call to one sandbox when your code keeps state in memory, such as a connection opened by a process initializer.

x-am-content-type-response

The format of the answer. Default : application/json.

Application/json

x-am-content-type-response: application/json
{ "success": true, "statusCode": 200, "data": [ { "customer_id": 4, "first_name": "JOHNNY", "last_name": "LOLLOBRIGIDA" } ] }

Text/xml

x-am-content-type-response: text/xml
<?xml version='1.0'?>
<root>
    <success>true</success>
    <statusCode>200</statusCode>
    <data>
        <_el>
            <customer_id>4</customer_id>
            <first_name>JOHNNY</first_name>
            <last_name>LOLLOBRIGIDA</last_name>
        </_el>
    </data>
</root>

Text/yaml

x-am-content-type-response: text/yaml
success: true
statusCode: 200
data:
    - customer_id: 4
      first_name: JOHNNY
      last_name: LOLLOBRIGIDA

Text/plain, text/html, application/octet-stream

x-am-content-type-response: text/plain
  • The same envelope as text, HTML or bytes. A custom API can also decide the format itself with g.res.contentType, see Content types.

x-am-cache-control

For an API with caching on. Default : no_action.

No action to cache

x-am-cache-control: no_action
  • The answer comes from Redis when it is there. The response header x-am-data-source says cache.

Reset cache

x-am-cache-control: reset_cache
  • The API runs against the database and its answer replaces the cached one. x-am-data-source says api.

x-am-get-encrypted-data

Encrypts the answer with encryptionAlgorithmFETransfer and secretFETransfer of the secret, the key you share with your frontend or mobile app. Default : no_encryption.

No encryption

{ "success": true, "statusCode": 200, "data": [ { "customer_id": 53, "first_name": "Deli", "last_name": "Augustus" } ] }

Get only encryption

x-am-get-encrypted-data: get_only_encryption
{ "success": true, "statusCode": 200, "data": null, "encryptedData": "U2FsdGVkX1+6qMdb3jXwJAUWH/qlwBq75mtA1kzpWccrNZRAr+CE2c3VtGpkEtVjH==" }

Get data and encryption

x-am-get-encrypted-data: get_data_and_encryption
{ "success": true, "statusCode": 200, "data": [ { "customer_id": 53, "first_name": "Deli", "last_name": "Augustus" } ], "encryptedData": "U2FsdGVkX1+6qMdb3jXwJAUWH/qlwBq75mtA1kzpWccrNZRAr+CE2c3VtGpkEtVjH==" }
  • The client decrypts encryptedData with the same algorithm and key (AES, RC4 or TripleDES, as in the secret).

x-am-encrypted-payload

Tells API Maker that the body is encrypted : { "dataEncFE": "…" }, where dataEncFE is { data, createdAt } encrypted with the transfer key of the secret. A payload older than feTransferDataValidityInSeconds is refused. With acceptOnlyEncryptedData: true in the settings, plain bodies are refused. See Security features.

x-am-encrypted-payload: true

x-am-tenant-username

The tenant of the request, for the APIs of a multi-tenant instance : they work on the database of that tenant.

  • It names the tenant only. Each multi-tenant instance looks the tenant up in its own tenants table, the entry of the default secret chosen as its Connection String Multi Tenant. So one header serves every multi-tenant instance a request or a custom API uses, even when they use different tenants tables.
  • It does what naming the tenant in the path does, after the instance name and two colons : /api/schema/admin/crm::acme/crm/customers. When a request does both, the tenant of the path is used.
  • A tenant the tenants table does not have, or which the find of its secret entry leaves out, is refused with 400 : Unable to find tenant with username 'acme'.
  • An empty value names no tenant : the request works on the structure database.
  • A custom API reads the tenant in g.req.params.tenantUsername, and passes it on to the APIs it calls with g.sys.db and g.sys.system. The hooks of the request do the same.
  • Custom, system and third party APIs with caching keep their cached answers per tenant.
  • A token of a user made with this header works for that tenant only.
  • An instance which is not multi-tenant has one database for every tenant : the header does not change the database it uses.
GET /api/schema/admin/crm/crm/customers
x-am-tenant-username: acme

x-am-sandbox-timeout

How long the code of this call (custom API, hooks, events, listeners) may run, in milliseconds. Default : sandboxReqTimeout of the configuration, 13000. When the time is over, the sandbox stops the code and the answer is an error.

x-am-sandbox-timeout: 60000
  • A custom API can set its own limit in its settings with customApiTimeoutInSeconds.

x-no-compression

Answers of at least compressThreshold bytes (51200 by default) are compressed. true sends this answer as it is.

  • A file sent by a custom API is compressed whatever its size. Streamed answers (the /stream APIs) are never compressed.
x-no-compression: true

accept-encoding

The standard header. API Maker picks the first of gzip, br (Brotli) and deflate which the header accepts : a browser sending gzip, deflate, br gets gzip, which costs far less CPU than Brotli for nearly the same size. Send accept-encoding: br to get Brotli. identity, or no header at all, means no compression.

accept-encoding: gzip

Response headers

Header Meaning
x-am-data-source cache when the answer came from Redis, api when the API ran. Always api for streams.
x-am-request-id The id of the request, the same in the logs of API Maker.
content-encoding br, gzip or deflate when the answer is compressed.

From your code

The same headers go in headers of every g.sys call :

const rows = await g.sys.db.getAll({
    instance: 'mysql8', database: 'inventory', collection: 'customers',
    headers: { 'x-am-response-case': 'camelCase', 'x-am-tenant-username': 'acme' },
});