# Changelog

## 0.8.1

Released 2026-10-08.

### `functions init` defaults to a new voice service and records what it created

The interactive voice picker now offers "Create a new one" first, and it is the default whenever the project has services; picking an existing service is opt-in. Non-interactive runs are unchanged.

- A service or number that init creates is saved in `sinch.json` as `createdResources`, with the name of the function init created it for. A picked service, or one passed with `--voice-service-id`, is never recorded.
- A `sinch functions deploy` of that function sends them, so deleting the function releases them. Deploy removes each one from `sinch.json` once the API reports it as recorded for the function.
- A deploy under another name (`--name`) does not send them. If the API does not record them, they stay in `sinch.json` and the next deploy sends them again.

If the API rejects a deploy because another function already records one of these resources as created, the error names that function and says to remove `createdResources` from `sinch.json`. A failed deploy now prints "Failed to deploy function:" once instead of twice.

### The CLI joins an inherited trace

When `TRACEPARENT` (W3C trace context, version 00) is set, every Functions API request forwards it unchanged, together with `TRACESTATE`, and the run's telemetry uses that trace id. `SINCH_CLIENT` and `SINCH_BUILDER_SESSION_ID` are sent as the `X-Sinch-Client` and `X-Sinch-Builder-Session` headers; they label diagnostics only, and invalid values are dropped. AI Builder sets these so each deploy is filed under its builder session. Without them the CLI behaves as before.

## 0.8.0

Released 2026-10-05.

### Connection settings come from your profile only

**Breaking for scripts:** a project's `sinch.json` can no longer set `projectId`, `apiUrl`, `oauthUrl`, `keyId`, or any credential or `oauth*` field; those values are ignored. If a folder's `sinch.json` names a different project than your active profile, commands now use the profile's project. To target another project, run `sinch config profile use <name>` (only `auth login` and `config get|set|list` honor the `--profile` flag; see [Configuration](/docs/functions/cli/configuration.md#config-profiles)). In CI, set `SINCH_KEY_ID`, `SINCH_KEY_SECRET` and `SINCH_PROJECT_ID` together. `functions download` no longer writes `projectId`. Folders downloaded earlier still work when your active profile is on the project they came from.

## 0.7.0

Released 2026-09-30.

### `functions init` can create a voice service and rent a number, and prints JSON

Voice templates now offer to create a Voice v2 service and, after showing the price and asking, rent a US LOCAL number linked to it. `VOICE_SERVICE_ID` and `VOICE_FROM_NUMBER` go into `.env`. New flags: `--create-voice-service`, `--rent-number <region>`, `--area-code <digits>`, `--force` (required to rent when non-interactive) and `--json`. New voice projects get `accessKey: "managed"` in `sinch.json`.

### `--json` on more commands

These commands now accept `--json`. Each prints one JSON document on stdout and never prompts. Where confirmation is needed and neither `--force` nor `--non-interactive` is given, `--json` fails with an error document naming `--force` and exits 66. `voice v1 conferences kick-all` (which also takes `--yes`), `functions download` (to overwrite), `storage delete`, the `sinch sip` delete commands, `auth logout` and `config profile delete` take only `--force` as confirmation.

- `sinch functions delete`, `download`, `validate`, `db download|upload`, `storage list|upload|download|delete`
- `sinch conversation` delete and stop commands (apps, contacts, conversations, messages, templates, webhooks), and `sinch sip` delete commands (acls, ACL IP ranges, endpoints, trunks) and `sip trunks acls remove`. `conversation conversations stop` and `conversation messages delete` gain `--force`, and a confirmation step they did not have before (see below).
- `sinch config` (all subcommands; `config profile delete` gains `--force`), `sinch secrets add|get|delete|clear` (`secrets list` already had `--json`), `sinch skills`, `sinch env init`
- `sinch auth status|login|logout`, `sinch health`. `auth login` needs `--credentials-file` under `--json`, and `auth logout` gains `--force`.
- `sinch numbers order resume`

`sinch functions logs` (one JSON object per line with `--follow`), `sinch fax download` and `sinch upgrade` also gain `--json`. `sinch voice v1 conferences kick-all` already accepted `--json`. It gains `-f, --force`, and `--yes` still works.

Under `--json`, missing or rejected credentials now print `{ "error": "..." }` on stdout and exit 100 or 101, with no login prompt.

### Some deletes with no terminal now exit 66

**Breaking for scripts:** with no terminal and no `-f, --force`, the `sinch sip` delete commands (acls, ACL IP ranges, endpoints, trunks) and `sip trunks acls remove` now exit 66 and change nothing. Before, they printed "Deletion cancelled" or "Operation cancelled" and exited 0.

`conversation conversations stop` and `conversation messages delete` now ask for confirmation. With no terminal and neither `-f, --force` nor `--non-interactive`, they exit 66 and do nothing. Before, they ran without asking.

### `sinch auth status` exits non-zero when no credentials are configured

**Breaking for scripts:** `sinch auth status` now exits 101 (`AUTH_FAILED`) when no credentials are configured, with and without `--json`. It used to exit 0. A script or CI step that ran it and treated exit 0 as success now sees a failure. With `--json` it prints `{ "authenticated": false }`.

Credentials that exist but are rejected, for example a wrong `SINCH_KEY_SECRET`, still exit 0. With `--json` the output has `"authenticated": true` and `"tokenValid": false`, so a CI check should read `tokenValid` rather than the exit code alone.

### `--json` list output is an object with a named array key

**Breaking for scripts:** every `--json` list is now an object with one named array key, which leaves room for pagination fields later. A script that indexed the array directly reads the key instead, for example `jq '.[0]'` becomes `jq '.faxes[0]'`.

| Command                                             | Before                    | Now                          |
| --------------------------------------------------- | ------------------------- | ---------------------------- |
| `sinch fax list --json`                             | `[...]`                   | `{ "faxes": [...] }`         |
| `sinch fax services list --json`                    | `[...]`                   | `{ "services": [...] }`      |
| `sinch fax services numbers <service-id> --json`    | `[...]`                   | `{ "numbers": [...] }`       |
| `sinch fax emails list --json`                      | `[...]`                   | `{ "emails": [...] }`        |
| `sinch fax emails numbers <email> --json`           | `[...]`                   | `{ "numbers": [...] }`       |
| `sinch fax cover-pages list --json`                 | `[...]`                   | `{ "coverPages": [...] }`    |
| `sinch fax send --json` (with and without `--wait`) | `[...]`                   | `{ "faxes": [...] }`         |
| `sinch numbers active list --json`                  | `[...]`                   | `{ "activeNumbers": [...] }` |
| `sinch numbers order list --json`                   | `[...]`, or text if empty | `{ "orders": [...] }`        |
| `sinch voice calls list --json`                     | `[...]`                   | `{ "calls": [...] }`         |
| `sinch voice services list --json`                  | `[...]`                   | `{ "services": [...] }`      |

Commands that already printed an object (conversation, sip, porting, templates, secrets, functions list) are unchanged.

### Other changes

- A failed API call exits with a code that follows its HTTP status: 401 exits 100, 403 exits 77, 404 exits 102, 409 exits 103, and 429 or 5xx exits 69. [CI/CD](./ci-cd.md#exit-codes) lists every code.
- `-a, --app-key` works on every Voice v1 command. On `voice v1 applications numbers list` it filters the listed numbers instead. `voice calls create` and `voice calls bridge` gain `--service-id`.
- `functions init` removes the half-created directory when stopped with Ctrl+C, and exits 130.
- New `sinch conversation apps update` command. It sends only the fields you pass.
- `sinch conversation apps create` no longer fails with HTTP 400 because it sent an empty body.
- `sinch functions dev` points the Voice and Conversation webhooks back at their deployed targets when it stops.
