{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-docs/functions/cli/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["partial"]},"type":"markdown"},"seo":{"title":"Changelog | Sinch CLI | Sinch","siteUrl":"https://developers.sinch.com","llmstxt":{"title":"Sinch Developer Documentation","description":"LLMs.txt containing a map of all the documentation files for Sinch.","sections":[{"title":"Numbers API","description":"The Numbers API enables you to search for, view, and activate numbers. It's considered a precursor to other APIs in the Sinch product family. The numbers API can be used in tandem with any of our APIs that perform messaging or calling.","includeFiles":["docs/numbers/**/*.md","docs/numbers/**/*.yaml"],"excludeFiles":["docs/numbers/index.md"]},{"title":"Conversation API","description":"Send and receive messages globally on SMS, RCS, WhatsApp, and other channels with Sinch's Conversation API. Conversation API is the API to use for all new SMS integrations with Sinch; its SMS channel replaces the standalone SMS REST API, which reached end of sale on 15 April 2026. Conversation API has unified error messages, consistent request payloads, and channel-agnostic webhook payloads.","includeFiles":["docs/conversation/**/*.md","docs/conversation/**/*.yaml"],"excludeFiles":["docs/conversation/index.md"]},{"title":"Standalone SMS REST API (end of sale, existing integrations only)","description":"The standalone SMS REST API reached end of sale on 15 April 2026 and is no longer available to new customers. All new SMS integrations must use the SMS channel of Conversation API (https://developers.sinch.com/docs/conversation/channel-support/sms/). Use these pages only to maintain an existing standalone SMS REST API integration, or to migrate it to Conversation API.","includeFiles":["docs/sms/**/*.md","docs/sms/**/*.yaml"],"excludeFiles":["docs/sms/index.md","docs/sms/**/md_snippets/**"]},{"title":"Voice API (legacy/GA)","description":"Which Voice API? If you are building something using voice AI agents, use the Voice API v2. To learn more, you can read [Why migrate to v2?](/docs/voice-2.0/migration.md) or [What's new?](/docs/voice-2.0/whatsnew.md).\n\nThe Voice API works as a big telephony switch. The Voice API handles incoming phone calls (also known as incoming call “legs”), sets up outgoing phone calls (or outgoing call “legs”), and bridges the two. The incoming call leg may come in over a data connection (from a smartphone or web application using the Sinch SDKs) or through a local phone number (from the PSTN network). Similarly, the outgoing call leg can be over data (to another smartphone or web application using the Sinch SDKs) or the PSTN network.","includeFiles":["docs/voice/**/*.md"],"excludeFiles":["docs/voice/index.md"]},{"title":"Voice API v2 (recommended for new builds/preview)","description":"Which Voice API? If you are building something using voice AI agents, use the Voice API v2. To learn more, you can read [Why migrate to v2?](/docs/voice-2.0/migration.md) or [What's new?](/docs/voice-2.0/whatsnew.md).\n\nThe Voice API v2 enables embedding voice calling into applications for virtually limitless use cases. From voice-enabling AI agents to allow real-time conversational AI workflows over the phone, to number masking for privacy, automated appointment reminders, and outreach campaigns with answering machine detection, to bridging calls between PSTN and SIP endpoints, the API offers the flexibility and control needed for modern communications. The Sinch Programmable Voice is a cloud-native global voice platform, composed by multiple Inbound and Outbound voice channels. All these channels can be combined using our powerful markup language called SVAML v2, creating a toolbox capable of building almost limitless use cases. Our SVAML uses the concept of commands, and customers can use a combination of our commands to interact with calls in all channels, in order to model from the most basic to highly complex scenarios, required to fulfill their voice calling needs.","includeFiles":["docs/voice-2.0/**/*.md"],"excludeFiles":["docs/voice-2.0/index.md"]},{"title":"Verification API","description":"The Verification API is a platform for phone number verification. It consists of the API and different software development kits (the Sinch SDKs) that you integrate with your smartphone or web application and cloud based back-end services. Together they enable SMS, Flashcall, Phone Call and Data verification in your application.","includeFiles":["docs/verification/**/*.md","docs/verification/**/*.yaml"],"excludeFiles":["docs/verification/index.md"]},{"title":"Provisioning API","description":"Provisioning API allows you to programmatically set up your senders, accounts and templates on your favorite messaging platforms on the Conversation API. For now, you can create your first WhatsApp channel through Meta's Embedded sign up, you can configure your first SMS App and configure your webhooks. As development continues, we will be adding the most commonly used channels.","includeFiles":["docs/provisioning-api/**/*.md","docs/provisioning-api/**/*.json"],"excludeFiles":["docs/provisioning-api/index.md"]},{"title":"Elastic SIP Trunking API","description":"With Elastic SIP Trunking you can create and manage your SIP trunks and phone numbers programmatically.","includeFiles":["docs/est/**/*.md","docs/est/**/*.yaml"],"excludeFiles":["docs/est/index.md"]},{"title":"Fax API","description":"Send and receive HIPAA compliant faxes on our modern fax platform using our developer-friendly API.","includeFiles":["docs/fax/**/*.md","docs/fax/**/*.yaml"],"excludeFiles":["docs/fax/index.md"]},{"title":"In-app Voice and Video SDK","description":"The In-app Voice and Video SDK enables you to add voice and video calling capabilities directly into your mobile or web application using the Sinch SDKs.","includeFiles":["docs/in-app-calling/**/*.md"],"excludeFiles":["docs/in-app-calling/index.md"]},{"title":"Number Lookup API","description":"The Number Lookup API is designed to provide in-depth information about phone numbers, helping enterprises enhance their communication strategies and prevent fraud. By identifying the type of phone line (for example, mobile, landline, VoIP) and the associated carrier, the API allows businesses to optimize routing, reduce unnecessary costs, and improve customer engagement.","includeFiles":["docs/number-lookup-api-v2/**/*.md","docs/number-lookup-api-v2/**/*.yaml"],"excludeFiles":["docs/number-lookup-api-v2/index.md"]},{"title":"Functions","description":"Serverless compute for voice and messaging. Deploy your code and Sinch routes live calls and messages to it — no infrastructure to run.","includeFiles":["docs/functions/functions/**/*.md","docs/functions/concepts/**/*.md","docs/functions/ai-support.md","docs/functions/reference/**/*.md"],"excludeFiles":["docs/functions/functions/index.md"]},{"title":"CLI","description":"One command line for Sinch numbers, messaging, voice, fax, SIP trunking and porting, and the full Functions lifecycle — scaffold, run locally, deploy, and manage.","includeFiles":["docs/functions/cli/**/*.md"],"excludeFiles":["docs/functions/cli/index.md"]}]},"description":"What changed in each Sinch CLI release."},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"changelog","__idx":0},"children":["Changelog"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"unreleased","__idx":1},"children":["Unreleased"]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-deploy-says-when-it-moves-a-function-to-cli-management","__idx":2},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions deploy"]}," says when it moves a function to CLI management"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The first CLI deploy of an existing function moves it to CLI management, which turns off the web editor, rollback from the dashboard and the Assistant for it. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions deploy"]}," now says so before packaging. Interactively it asks to continue (default: yes), and declining deploys nothing. With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--non-interactive"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CI"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," or no terminal, it prints the notice and deploys; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," includes it in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warnings"]},"."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No notice for a new function, a function already managed from the CLI, or a deploy with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_CLIENT=ai-builder"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A function deployed from the CLI before this change may show the notice once more."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Warnings about the recorded function and the notice are no longer dropped from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["warnings"]}," when validation runs."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-versions-and-functions-rollback","__idx":3},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions versions"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions rollback"]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions versions"]}," lists a function's versions, and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions rollback <version>"]}," restores an earlier version's code as a new version. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<version>"]}," is the number ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["versions"]}," shows or the version's id."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Rollback restores code only, not environment variables or database data. It confirms first when it can prompt, waits for the build (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--no-wait"]}," skips that), and refuses a version whose build failed with exit code ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["103"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Rollback doesn't change ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},". Run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions download"]}," to pull the restored code; a deploy from the old copy is refused as stale until you do."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Errors from the API now show the API's detail in the CLI's message."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-deploy-updates-against-the-version-your-copy-came-from","__idx":4},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions deploy"]}," updates against the version your copy came from"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions deploy"]}," now updates the function recorded in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," by its id, and sends the recorded ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["versionId"]}," as the base version. If the function changed since your copy was taken, deploy asks before overwriting it, or exits with code ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["103"]}," when it can't ask (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--non-interactive"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CI"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},"). A copied folder deployed under a new name creates that function instead of touching the original, with a warning that the recorded function wasn't used."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--overwrite"]}," deploys without the base-version check. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]}," does not skip it."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--message <text>"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-m"]},") saves a note on the new version."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Deploy records ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["versionId"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},", and includes it in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," output."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A deploy under a different ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--name"]}," no longer overwrites ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functionId"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},". Before, a preview deploy moved the project to the preview function."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions download"]}," records the live version's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["versionId"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},", and fails without leaving files behind when the function's configuration can't be fetched. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions list"]}," shows a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Display Name"]}," column and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions status"]}," prints the display name."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"082","__idx":5},"children":["0.8.2"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Released 2026-10-19."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-deploy-sends-values-with-credential-names-as-secrets","__idx":6},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions deploy"]}," sends values with credential names as secrets"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions deploy"]}," now sends a filled ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".env"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["appsettings.json"]}," value as a secret when its name looks like a credential. Before, every filled value was sent as plain configuration and showed in the dashboard. The function reads both kinds from its environment as before, and deploy's list of variables marks these ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["(secret)"]},". See ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/functions/functions/concepts/configuration-secrets"},"children":["Configuration and secrets"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A name looks like a credential when its last word is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["KEY"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["KEYS"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["APIKEY"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SECRET"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SECRETS"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TOKEN"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PASSWORD"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PASSWD"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PASS"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PWD"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PASSPHRASE"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CREDENTIAL"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CREDENTIALS"]},", and none of its words is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUBLIC"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUBLISHABLE"]},". Names are split into words on non-alphanumeric characters and where a lowercase letter is followed by an uppercase one. An all-caps run is not split."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Sent as secrets: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OPENAI_API_KEY"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GITHUB_TOKEN"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SMTP_PASS"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Kept plain: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["MAX_TOKENS"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TOKEN_URL"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AWS_ACCESS_KEY_ID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PUBLIC_KEY"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["OpenAIKey"]},", and a filled ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PROJECT_ID_API_KEY"]}," or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VOICE_APPLICATION_KEY"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For C#, only top-level ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["appsettings.json"]}," keys count. Because the file also ships inside the package, deploy warns with the key names (not under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},") and points you to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["dotnet user-secrets"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A value that has deployed as a secret stays a secret, so renaming the key is the only way to make it plain again. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions download"]}," treats it like any other secret: it is blank in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".env"]},", with an offer to fetch its value into your keychain. If you decline, or the run cannot prompt, a later deploy from that folder warns and leaves the key out of the function."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-developer-skills-offer-can-install-for-one-project","__idx":7},"children":["The developer skills offer can install for one project"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The offer to install the Sinch developer skills now asks ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["This project only"]}," (followed by the folder's path), ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Globally (all projects)"]}," or ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Skip"]},", instead of yes or no for a global install."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["After ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch auth login"]},", the project choice shows only when the current folder has a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions init"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions download"]}," make the offer at the end, for the folder they created."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Skip"]}," is saved as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["skipSkillsPrompt"]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["~/.sinch/config.json"]}," and stops the offer everywhere. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch skills install"]}," still installs the skills later."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--non-interactive"]}," and runs with no terminal never ask."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A project install writes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".agents"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".claude"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["skills-lock.json"]},", so ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions deploy"]}," now leaves files and folders with those names out of the package, anywhere in the function folder."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-logs--n-limits-the-number-of-entries","__idx":8},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions logs -n"]}," limits the number of entries"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions logs -n <N>"]}," now returns at most N entries (the API caps it at 500). Before, the CLI sent a parameter the API never read, so ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-n"]}," had no effect. Without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-n"]}," the API still returns up to 100 entries, and the help text now says 100 (it said 50). ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-n"]}," now rejects anything that is not a positive whole number, with exit 64. With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--follow"]}," it is still checked but has no effect."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"commands-no-longer-keep-spinning-after-a-login-retry","__idx":9},"children":["Commands no longer keep spinning after a login retry"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["After a login retry, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions list"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["download <function-id>"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["delete"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["logs"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["db"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch templates list"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["show"]},", now exit when the retried command finishes. Before, if you ran one of them logged out (or with stored credentials that no longer work) and logged in at the prompt, it did its work and then kept spinning until Ctrl+C. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["logs --follow"]}," still streams until Ctrl+C."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"other-changes","__idx":10},"children":["Other changes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions docs --update"]}," no longer fails every time with a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".find is not a function"]}," error. It looks up the function named after the current folder on every page of the function list."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Download errors from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions download"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage download"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["db download"]},", and from the template download in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions init"]},", now show the API's message when the error has one, instead of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Request failed with status code N"]},". Exit codes and message prefixes are unchanged."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"081","__idx":11},"children":["0.8.1"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Released 2026-10-08."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-init-defaults-to-a-new-voice-service-and-records-what-it-created","__idx":12},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions init"]}," defaults to a new voice service and records what it created"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A service or number that init creates is saved in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createdResources"]},", with the name of the function init created it for. A picked service, or one passed with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--voice-service-id"]},", is never recorded."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions deploy"]}," of that function sends them, so deleting the function releases them. Deploy removes each one from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," once the API reports it as recorded for the function."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["A deploy under another name (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--name"]},") does not send them. If the API does not record them, they stay in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," and the next deploy sends them again."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createdResources"]}," from ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},". A failed deploy now prints \"Failed to deploy function:\" once instead of twice."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"the-cli-joins-an-inherited-trace","__idx":13},"children":["The CLI joins an inherited trace"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TRACEPARENT"]}," (W3C trace context, version 00) is set, every Functions API request forwards it unchanged, together with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["TRACESTATE"]},", and the run's telemetry uses that trace id. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_CLIENT"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_BUILDER_SESSION_ID"]}," are sent as the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["X-Sinch-Client"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["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."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"080","__idx":14},"children":["0.8.0"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Released 2026-10-05."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"connection-settings-come-from-your-profile-only","__idx":15},"children":["Connection settings come from your profile only"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Breaking for scripts:"]}," a project's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," can no longer set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["projectId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["apiUrl"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oauthUrl"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["keyId"]},", or any credential or ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["oauth*"]}," field; those values are ignored. If a folder's ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," names a different project than your active profile, commands now use the profile's project. To target another project, run ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch config profile use <name>"]}," (only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auth login"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["config get|set|list"]}," honor the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--profile"]}," flag; see ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/docs/functions/cli/configuration#config-profiles"},"children":["Configuration"]},"). In CI, set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_KEY_ID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_KEY_SECRET"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_PROJECT_ID"]}," together. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions download"]}," no longer writes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["projectId"]},". Folders downloaded earlier still work when your active profile is on the project they came from."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"070","__idx":16},"children":["0.7.0"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Released 2026-09-30."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"functions-init-can-create-a-voice-service-and-rent-a-number-and-prints-json","__idx":17},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions init"]}," can create a voice service and rent a number, and prints JSON"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["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. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VOICE_SERVICE_ID"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VOICE_FROM_NUMBER"]}," go into ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".env"]},". New flags: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--create-voice-service"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--rent-number <region>"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--area-code <digits>"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]}," (required to rent when non-interactive) and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},". New voice projects get ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["accessKey: \"managed\""]}," in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"--json-on-more-commands","__idx":18},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," on more commands"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["These commands now accept ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},". Each prints one JSON document on stdout and never prompts. Where confirmation is needed and neither ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]}," nor ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--non-interactive"]}," is given, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," fails with an error document naming ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]}," and exits 66. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["voice v1 conferences kick-all"]}," (which also takes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--yes"]},"), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions download"]}," (to overwrite), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage delete"]},", the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch sip"]}," delete commands, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auth logout"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["config profile delete"]}," take only ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]}," as confirmation."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions delete"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["download"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["validate"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["db download|upload"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["storage list|upload|download|delete"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch conversation"]}," delete and stop commands (apps, contacts, conversations, messages, templates, webhooks), and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch sip"]}," delete commands (acls, ACL IP ranges, endpoints, trunks) and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sip trunks acls remove"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["conversation conversations stop"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["conversation messages delete"]}," gain ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]},", and a confirmation step they did not have before (see below)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch config"]}," (all subcommands; ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["config profile delete"]}," gains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]},"), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch secrets add|get|delete|clear"]}," (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["secrets list"]}," already had ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},"), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch skills"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch env init"]}]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch auth status|login|logout"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch health"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auth login"]}," needs ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--credentials-file"]}," under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["auth logout"]}," gains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--force"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch numbers order resume"]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions logs"]}," (one JSON object per line with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--follow"]},"), ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax download"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch upgrade"]}," also gain ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},". ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch voice v1 conferences kick-all"]}," already accepted ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},". It gains ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-f, --force"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--yes"]}," still works."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Under ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]},", missing or rejected credentials now print ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"error\": \"...\" }"]}," on stdout and exit 100 or 101, with no login prompt."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"some-deletes-with-no-terminal-now-exit-66","__idx":19},"children":["Some deletes with no terminal now exit 66"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Breaking for scripts:"]}," with no terminal and no ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-f, --force"]},", the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch sip"]}," delete commands (acls, ACL IP ranges, endpoints, trunks) and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sip trunks acls remove"]}," now exit 66 and change nothing. Before, they printed \"Deletion cancelled\" or \"Operation cancelled\" and exited 0."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["conversation conversations stop"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["conversation messages delete"]}," now ask for confirmation. With no terminal and neither ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-f, --force"]}," nor ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--non-interactive"]},", they exit 66 and do nothing. Before, they ran without asking."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"sinch-auth-status-exits-non-zero-when-no-credentials-are-configured","__idx":20},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch auth status"]}," exits non-zero when no credentials are configured"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Breaking for scripts:"]}," ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch auth status"]}," now exits 101 (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["AUTH_FAILED"]},") when no credentials are configured, with and without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--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 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," it prints ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"authenticated\": false }"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Credentials that exist but are rejected, for example a wrong ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SINCH_KEY_SECRET"]},", still exit 0. With ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," the output has ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"authenticated\": true"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["\"tokenValid\": false"]},", so a CI check should read ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["tokenValid"]}," rather than the exit code alone."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"--json-list-output-is-an-object-with-a-named-array-key","__idx":21},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--json"]}," list output is an object with a named array key"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Breaking for scripts:"]}," every ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--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 ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["jq '.[0]'"]}," becomes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["jq '.faxes[0]'"]},"."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Command"},"children":["Command"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Before"},"children":["Before"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Now"},"children":["Now"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"faxes\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax services list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"services\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax services numbers <service-id> --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"numbers\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax emails list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"emails\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax emails numbers <email> --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"numbers\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax cover-pages list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"coverPages\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch fax send --json"]}," (with and without ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--wait"]},")"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"faxes\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch numbers active list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"activeNumbers\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch numbers order list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]},", or text if empty"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"orders\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch voice calls list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"calls\": [...] }"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch voice services list --json"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["[...]"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["{ \"services\": [...] }"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Commands that already printed an object (conversation, sip, porting, templates, secrets, functions list) are unchanged."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"other-changes-1","__idx":22},"children":["Other changes"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["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. ",{"$$mdtype":"Tag","name":"MarkdownLink","attributes":{"href":"/assets/ci-cd.66afb53ca35033512942b50d6ad0ff9e0768727ac2c2100f305647ab37d7185b.8a245974.md"},"children":["CI/CD"]}," lists every code."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["-a, --app-key"]}," works on every Voice v1 command. On ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["voice v1 applications numbers list"]}," it filters the listed numbers instead. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["voice calls create"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["voice calls bridge"]}," gain ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["--service-id"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["functions init"]}," removes the half-created directory when stopped with Ctrl+C, and exits 130."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["New ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch conversation apps update"]}," command. It sends only the fields you pass."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch conversation apps create"]}," no longer fails with HTTP 400 because it sent an empty body."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions dev"]}," points the Voice and Conversation webhooks back at their deployed targets when it stops."]}]}]},"headings":[{"value":"Changelog","id":"changelog","depth":1},{"value":"Unreleased","id":"unreleased","depth":2},{"value":"functions deploy says when it moves a function to CLI management","id":"functions-deploy-says-when-it-moves-a-function-to-cli-management","depth":3},{"value":"functions versions and functions rollback","id":"functions-versions-and-functions-rollback","depth":3},{"value":"functions deploy updates against the version your copy came from","id":"functions-deploy-updates-against-the-version-your-copy-came-from","depth":3},{"value":"0.8.2","id":"082","depth":2},{"value":"functions deploy sends values with credential names as secrets","id":"functions-deploy-sends-values-with-credential-names-as-secrets","depth":3},{"value":"The developer skills offer can install for one project","id":"the-developer-skills-offer-can-install-for-one-project","depth":3},{"value":"functions logs -n limits the number of entries","id":"functions-logs--n-limits-the-number-of-entries","depth":3},{"value":"Commands no longer keep spinning after a login retry","id":"commands-no-longer-keep-spinning-after-a-login-retry","depth":3},{"value":"Other changes","id":"other-changes","depth":3},{"value":"0.8.1","id":"081","depth":2},{"value":"functions init defaults to a new voice service and records what it created","id":"functions-init-defaults-to-a-new-voice-service-and-records-what-it-created","depth":3},{"value":"The CLI joins an inherited trace","id":"the-cli-joins-an-inherited-trace","depth":3},{"value":"0.8.0","id":"080","depth":2},{"value":"Connection settings come from your profile only","id":"connection-settings-come-from-your-profile-only","depth":3},{"value":"0.7.0","id":"070","depth":2},{"value":"functions init can create a voice service and rent a number, and prints JSON","id":"functions-init-can-create-a-voice-service-and-rent-a-number-and-prints-json","depth":3},{"value":"--json on more commands","id":"--json-on-more-commands","depth":3},{"value":"Some deletes with no terminal now exit 66","id":"some-deletes-with-no-terminal-now-exit-66","depth":3},{"value":"sinch auth status exits non-zero when no credentials are configured","id":"sinch-auth-status-exits-non-zero-when-no-credentials-are-configured","depth":3},{"value":"--json list output is an object with a named array key","id":"--json-list-output-is-an-object-with-a-named-array-key","depth":3},{"value":"Other changes","id":"other-changes-1","depth":3}],"frontmatter":{"seo":{"title":"Changelog | Sinch CLI | Sinch","description":"What changed in each Sinch CLI release."}},"lastModified":"2026-10-12T21:36:30.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/functions/cli/changelog","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}