Protocol specification for https.onCall

Anhttps.onCall trigger for Cloud Functions is an HTTPS trigger with aspecific format for the request and response. This section provides aspecification for the HTTPS request and response formats used by the client SDKsto implement the API. This information may be useful to you if your requirementscan't be met using the Android, Apple platforms, or web SDKs.

Note: If youare able to use the Android, Apple, or web SDKs, you're recommendedto do that instead of directly implementing this protocol. The SDKs providefeatures to save coding time and effort, as detailed inCall Functions from Your App.

Request format: headers

The HTTP request to a callable trigger endpoint must be aPOST with thefollowing headers:

  • Required:Content-Type: application/json
    • An optional; charset=utf-8 is allowed.
  • Optional:Authorization: Bearer <token>
    • AFirebase Authentication user ID token for the logged-in user making the request. The backend automaticallyverifies this token and makes it available in the handler'scontext. If the token is not valid, the request is rejected.
  • Optional:Firebase-Instance-ID-Token: <iid>
    • The FCM registration token from the Firebase client SDK. This must be a string. This is available in the handler'scontext. It is used for targeting push notifications.
  • Optional:X-Firebase-AppCheck: <token>
    • The Firebase App Check token provided by the client app making therequest. The backend automatically verifies this token and decodes it,injecting theappId in the handler'scontext. If the token cannot beverified, the request is rejected. (Available for SDK >=3.14.0)

If any other headers are included, the request is rejected, as described in the response documentation below.

Note: In JavaScript clients, these requests trigger a CORSOPTIONS preflight, because:

  • application/json is not allowed. It must betext/plain orapplication/x-www-form-urlencoded.
  • TheAuthorization header is not aCORS-safelisted request-header.
  • Other headers are similarly not allowed.

The callable trigger automatically handles theseOPTIONS requests.

Request body

The body of the HTTP request should be a JSON object with any of the following fields:

  • Required:data - The argument passed to the function. This can be any valid JSON value. This is automatically decoded into native JavaScript types according to the serialization format described below.

If there are any other fields present in the request, the backend considers the request malformed, and it is rejected.

Response format: status codes

There are several cases that could result in different HTTP status codes andstring status codes forerrorsin the response.

  1. In the case of an HTTP error before theclient trigger is invoked, the response is not handled as a client function. For example, if a client tries to invoke a non-existent function, it receives a404 Not Found response.

  2. If the client trigger is invoked, but the request is in the wrong format, such as not being JSON, having invalid fields, or missing thedata field, the request is rejected with400 Bad Request, with an error code ofINVALID_ARGUMENT.

  3. If the auth token supplied in the request is invalid, the request is rejected with401 Unauthorized, with an error code ofUNAUTHENTICATED.

  4. If the FCM registration token supplied in the request is invalid, the behavior is undefined. The token is not checked on every request, except when it is used to send a push notification with FCM.

  5. If the callable trigger is invoked, but fails with an unhandled exception or returns a failed promise, the request is rejected with500 Internal Server Error, with an error code ofINTERNAL. This prevents coding errors from accidentally being exposed to end users.

  6. If the callable is invoked and returns an explicit error condition using the API provided for callable functions, then the request fails. The HTTP status code returned is based on the official mapping of error status to HTTP status, as defined incode.proto. The specific error code, message, and details returned are encoded in the response body as detailed below. This means that if the function returns an explicit error with statusOK, then the response has status200 OK, but theerror field is set in the response.

  7. If the client trigger is successful, the response status is200 OK.

Response format: headers

The response has the following headers:

  • Content-Type: application/json
  • An optional; charset=utf-8 is allowed.

Response body

The response from a client endpoint is always a JSON object. At a minimum itcontains eitherresult orerror, along with any optional fields. If theresponse is not a JSON object, or does not containdata orerror, theclient SDK should treat the request as failedwith Google error codeINTERNAL (13).

  • error - If this field is present, then the request is considered failed, regardless of the HTTP status code or whetherdata is also present. The value of this field should be a JSON object in the standardGoogle Cloud HTTP Mapping format for errors, with fields forstatus,message, and (optionally)details. Thecode field shall not be included. If thestatus field is unset, or is an invalid value, the client should treat the status asINTERNAL, in accordance withcode.proto. Ifdetails is present, it is included in any user info attached to the error in the client SDK, if applicable.
    Note: Thedetails field here is a user-supplied value. It is not necessarily a list of values keyed by proto type as in the GoogleStatus format.
  • result - The value returned by the function. This can be any valid JSON value. The firebase-functions SDK automatically encodes the value returned by the user into this JSON format. The client SDKs automatically decode these params into native types according to the serialization format described below.

If other fields are present, they should be ignored.

Serialization

The serialization format for arbitrary data payloads is the same for both the request and the response.

For platform consistency, these are encoded in JSON as though they are the value of anAny field in a proto3 protocol buffer, using thestandard JSON mapping. Values of simple types such asnull,int,double, orstring are encoded directly, and do not include their explicit type. So, afloat anddouble are encoded the same way, and you may not know which is received on the other end of the call. For types that are not native to JSON, the typed proto3 encoding for the value is used. For more information, see thedocumentation for Any JSON encoding.

The following types are allowed:

NaN andInfinity values forfloat anddouble are not supported.

Note thatlong is a special type not normally allowed in JSON, but is covered by the proto3 specification. For example, these are encoded as:

long

{'@type':'type.googleapis.com/google.protobuf.Int64Value','value':'-123456789123456'}

unsigned long

{'@type':'type.googleapis.com/google.protobuf.UInt64Value','value':'123456789123456'}

In general, the@type key should be considered reserved, and not used for maps passed in.

Because the type is not specified for simple types, some values will change type after passing over the wire. Afloat passed in becomes adouble. Ashort becomes anint, and so on. In Android, bothList andJSONArray are supported for list values. In those cases, passing in a JSONArray will yield aList.

If a map with an unknown@type field is deserialized, it is left as a map. This allows developers to add fields with new types to their return values without breaking older clients.

Code samples

The samples in this section illustrate how to encode the following:

  • A callable.call example in Swift
  • A success response for the call
  • A failure response for the call

Callable.call example in Swift to encode

callable.call([    "aString": "some string",    "anInt": 57,    "aFloat": 1.23,    "aLong": -123456789123456 as Int64])

Request header:

Method:POSTContent-Type:application/json;charset=utf-8Authorization:Bearersome-auth-tokenFirebase-Instance-ID-Token:some-iid-token

Request body:

{"data":{"aString":"some string","anInt":57,"aFloat":1.23,"aLong":{"@type":"type.googleapis.com/google.protobuf.Int64Value","value":"-123456789123456"}}}

Response to encode

return {    "aString": "some string",    "anInt": 57,    "aFloat": 1.23};

Successful response header:

200OKContent-Type:application/json;charset=utf-8

Successful response body:

{    "response": {        "aString": "some string",        "anInt": 57,        "aFloat": 1.23    }}

Failure response to encode

throw new HttpsError("unauthenticated", "Request had invalid credentials.", {  "some-key": "some-value"});

Failed response header:

401UNAUTHENTICATEDContent-Type:application/json;charset=utf-8

Failed response body:

{    "error": {        "message": "Request had invalid credentials.",        "status": "UNAUTHENTICATED",        "details": {            "some-key": "some-value"        }    }}

Except as otherwise noted, the content of this page is licensed under theCreative Commons Attribution 4.0 License, and code samples are licensed under theApache 2.0 License. For details, see theGoogle Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Last updated 2026-02-05 UTC.