#  Chat gRPC API 

## Request metadata

Clients may provide headers for gRPC requests via [gRPC metadata](https://grpc.io/docs/guides/metadata/) which translates directly to HTTP/2 headers.

- Clients should provide a `User-Agent` header on all gRPC requests.  
- Clients may provide an `Accept-Language` on any gRPC requests.

## Authentication

To authenticate for a specific signal account + device, clients may provide a [Basic authorization header](https://www.rfc-editor.org/info/rfc7617/)
on the request. The username must be the account identifier encoded in the 8-4-4-4-12 format followed by a '.'
character and then the device id serialized as a string.

All services either require or forbid providing authentication via an Authorization header. If the service is annotated
with the `require.auth` option `AUTH_ONLY_AUTHENTICATED`, all requests to the service must contain valid authentication
headers. If the service is annotated with the option `AUTH_ONLY_ANONYMOUS` the client must not provide an authorization
header. If provided, the request will fail with a `BAD_AUTHENTICATION` error.

## Errors

In the gRPC protocol all errors are at the request level. That is, errors are returned in response to individual requests and do not impact other H2 streams on the same connection nor terminate the connection.

For errors that may be returned by any RPCs, the chat server will return the well-defined gRPC status codes returned as part of every RPC call. For errors that are specific to a particular RPC, the error must be encoded in the service proto definition and will be returned with a `Status` of `OK`.

Status errors include additional metadata as described in [AIP-193 (google's richer error model)](https://google.aip.dev/193#error_model). Every `Status != OK` response returned by the chat server's application layer will include a `Grpc-Status-Details-Bin` response trailer with a `google.rpc.Status` proto.

Each `google.rpc.Status` must have a status matching the top-level status on the gRPC response. Additionally, a single `ErrorInfo` must always be present in the details field of the `Status`. The `ErrorInfo` must contain a `domain` field and a `reason` field.

The `domain` for a status error generated by the chat server will always be `grpc.chat.signal.org`

The server may set the `reason` to match the enum string for the `Status.Code` if there is no need to further distinguish a code. Clients should inspect the `reason`, not the `status`, for automated error handling.

The chat server may return the following errors from any RPC

| Status Code          | Reason                | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
|:---------------------|:----------------------|: |
| `INVALID_ARGUMENT`   | `UPGRADE_REQUIRED`    | The client version provided in the `User-Agent` is no longer supported. The client must upgrade to use the service.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `INVALID_ARGUMENT`   | `CONSTRAINT_VIOLATED` | The RPC argument violated a constraint that was annotated or documented in the service definition. It is always possible to check this constraint without communicating with the chat server. This always represents a client bug or out of date client. <br><br> The `details` may include a [`BadRequest` message](https://github.com/googleapis/googleapis/blob/8c06c1e04ae562f49f411357577c700e9142f33c/google/rpc/error_details.proto#L236) that indicates additional information about the invalid field.                                                                                                       |
| `INVALID_ARGUMENT`   | `BAD_AUTHENTICATION`  | The request has incorrectly set authentication credentials for the RPC. This represents a client bug where the authorization mode is not correct for the RPC. For example, <br><br> The RPC was for an anonymous service, but included an Authentication header in the RPC metadata. <br><br>The RPC should only be made by the primary device, but the request had linked device credentials.                                                                                                                                                                                                                        |
| `UNAUTHENTICATED`    | `INVALID_CREDENTIALS` | The account credentials provided in the authorization header are not valid.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `RESOURCE_EXHAUSTED` | `RESOURCE_EXHAUSTED`  | A server-side resource was exhausted. The `details` field may include a [`RetryInfo` message](https://github.com/googleapis/googleapis/blob/8c06c1e04ae562f49f411357577c700e9142f33c/google/rpc/error_details.proto#L92) that includes the amount of time in seconds the client should wait before retrying the request. <br><br> If a `RetryInfo` is present, the client must wait the indicated time before retrying the request. If absent, the client should retry with an exponential backoff.                                                                                                                   |
| `ABORTED`            | `STREAM_CLOSED`       | The server terminated a streaming RPC for some domain specific reason. The `details` field must include a message with additional information about why the stream was closed. This message must be defined in the corresponding service proto for the streaming RPC. This status must only be returned from server-side streaming RPCs. Clients must handle a STREAM_CLOSED status even if no corresponding message is defined in the version of the proto they are targeting. Unless otherwise noted, if a stream termination message is defined, clients must handle the error at any point in the message stream. |
| `UNAVAILABLE`        | `UNAVAILABLE`         | There was an internal error processing the RPC. The client should retry the request with exponential backoff.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |

### Logging Errors

When logging error responses, clients may always log the status code, domain, and reason.

For errors with domain `grpc.chat.signal.org` and reason `CONSTRAINT_VIOLATED`, clients should check the `details` field for a `BadRequest` proto. If present, they should log the `field` of each violation in `field_violations`.
