{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-docs/functions/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["partial"]},"type":"markdown"},"seo":{"title":"Developer Documentation","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":"SMS API","description":"The SMS API allows you to send and receive SMS messages with a few easy steps. You can also send bulk SMS messages to multiple customers using the Sinch SMS service.","includeFiles":["docs/sms/**/*.md","docs/sms/**/*.yaml"],"excludeFiles":["docs/sms/index.md"]},{"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 many popular channels with ease and confidence when using Sinch's Conversation API. Conversation API is the preferred API for sending mobile messages on SMS and other social channels with Sinch. It is a simple API with unified error messages, consistent request payloads, and common webhook payloads that are channel-agnostic.","includeFiles":["docs/conversation/**/*.md","docs/conversation/**/*.yaml"],"excludeFiles":["docs/conversation/index.md"]},{"title":"Voice API","description":"The 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","docs/voice/**/*.yaml"],"excludeFiles":["docs/voice/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"]}],"hide":false,"excludeFiles":[]}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":1,"id":"context-object","__idx":0},"children":["Context object"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Every handler receives a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FunctionContext"]}," as its first argument (Node) or as an injected dependency (C#). Think of it as the standard library of the Sinch runtime — everything you need to interact with state, configuration, and the rest of Sinch is hanging off of it."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"whats-in-it","__idx":1},"children":["What's in it"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Both runtimes expose the same capabilities with idiomatic names."]},{"$$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":"Capability"},"children":["Capability"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Node.js"},"children":["Node.js"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"C#"},"children":["C#"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Key-value cache"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.cache"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Cache"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Blob / file storage"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.storage"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Storage"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["SQLite database"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.database"]}," (path)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Database"]}," (conn)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Structured logger"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.log"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["console"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Logger"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Project + function info"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.config"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Configuration"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Env vars"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.env"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Configuration"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Request metadata"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.requestId"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":[".timestamp"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Available via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["HttpContext"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Pre-wired Voice SDK"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.voice"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Voice"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Pre-wired Conversation SDK"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.conversation"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Conversation"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Pre-wired SMS SDK"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.sms"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Sms"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Pre-wired Numbers SDK"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.numbers"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Numbers"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Pre-wired Verification SDK"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["—"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Verification"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Read private assets"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.assets(filename)"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Package-level helpers"]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK client properties are ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["undefined"]}," if the corresponding environment variables are not set — see ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"#"},"children":["configuration & secrets"]}," for which vars unlock which client."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"cache","__idx":2},"children":["Cache"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Key-value store with TTL. Use it for per-call state (keyed by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["callid"]},"), rate limiting, session data, and anything you want to survive between callbacks without a full database trip."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Dev:"]}," in-memory. Lost on restart."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Prod:"]}," persistent, shared across invocations, distributed."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"// Node\nawait context.cache.set('session:abc', { userId: 'u1' }, 1800);\nconst session = await context.cache.get<{ userId: string }>('session:abc');\nawait context.cache.extend('session:abc', 600);\nawait context.cache.delete('session:abc');\nconst keys = await context.cache.keys('session:*');\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"// C#\nawait Context.Cache.Set(\"session:abc\", new { UserId = \"u1\" }, 1800);\nvar session = await Context.Cache.Get<MySession>(\"session:abc\");\nif (await Context.Cache.Exists(\"session:abc\"))\n    await Context.Cache.Delete(\"session:abc\");\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Default TTL is 3600 seconds. Values are JSON-serialized."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"storage","__idx":3},"children":["Storage"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Blob storage for persistent files — call recordings, reports, user uploads, arbitrary data."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Dev:"]}," local filesystem in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["./storage/"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Prod:"]}," durable cloud storage with a local read cache."]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"// Node\nawait context.storage.write('reports/daily.json', JSON.stringify(data));\nconst buf = await context.storage.read('reports/daily.json');\nconst files = await context.storage.list('reports/');\nconst exists = await context.storage.exists('reports/old.json');\nawait context.storage.delete('reports/old.json');\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"// C#\nawait Context.Storage.WriteAsync(\"reports/daily.json\", JsonSerializer.Serialize(data));\nvar text = await Context.Storage.ReadTextAsync(\"reports/daily.json\");\nvar files = await Context.Storage.ListAsync(\"reports/\");\n\n// Streaming for big files\nusing var stream = await Context.Storage.ReadStreamAsync(\"large-file.bin\");\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Keys can include path separators — treat them like folder paths."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"database","__idx":4},"children":["Database"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["A per-function SQLite database. You bring your own SQLite library; the runtime manages the file location and replication."]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Dev:"]}," plain local SQLite file in ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["./data/"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Prod:"]}," SQLite with automatic durable replication. The database survives restarts and scale events, with no code changes required."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"node--sqljs-recommended","__idx":5},"children":["Node — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sql.js"]}," (recommended)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Pure JavaScript SQLite compiled to WebAssembly. No native compilation."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"import initSqlJs from 'sql.js';\nimport { readFileSync, writeFileSync, existsSync } from 'fs';\n\nconst SQL = await initSqlJs();\nconst buf = existsSync(context.database) ? readFileSync(context.database) : undefined;\nconst db = new SQL.Database(buf);\n\ndb.run('CREATE TABLE IF NOT EXISTS kv (key TEXT PRIMARY KEY, value TEXT)');\ndb.run('INSERT OR REPLACE INTO kv VALUES (?, ?)', ['greeting', 'hello']);\n\nwriteFileSync(context.database, Buffer.from(db.export()));\ndb.close();\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["better-sqlite3"]}," is faster but needs native compilation — use it when you can guarantee the build environment has ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["python3"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["make"]}," / ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["g++"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"c--microsoftdatasqlite","__idx":6},"children":["C# — ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Microsoft.Data.Sqlite"]}]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"using var conn = new SqliteConnection(Context.Database.ConnectionString);\nconn.Open();\n\nusing var cmd = conn.CreateCommand();\ncmd.CommandText = \"CREATE TABLE IF NOT EXISTS call_log (id INTEGER PRIMARY KEY, caller TEXT, ts INTEGER)\";\ncmd.ExecuteNonQuery();\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Or with Dapper:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"using var conn = new SqliteConnection(Context.Database.ConnectionString);\nvar calls = await conn.QueryAsync<CallRecord>(\"SELECT * FROM call_log ORDER BY ts DESC LIMIT 10\");\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"config-and-variables","__idx":7},"children":["Config and variables"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.config"]}," exposes project and function metadata — useful for logging, feature flags by environment, and constructing return URLs."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"context.config.projectId       // your Sinch Project ID\ncontext.config.functionName    // e.g. 'my-ivr'\ncontext.config.environment     // 'development' | 'production'\ncontext.config.variables       // object of sinch.json variables\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For a richer API, use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createConfig(context)"]}," (aka ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["createUniversalConfig"]},"):"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"import { createConfig } from '@sinch/functions-runtime';\n\nconst config = createConfig(context);\nconst apiKey = config.requireSecret('STRIPE_SECRET_KEY'); // throws if missing\nconst company = config.getVariable('COMPANY_NAME', 'Acme Corp');\nif (config.isProduction()) { /* ... */ }\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In C#, use the injected ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["IConfiguration"]},":"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"var companyName = Configuration[\"COMPANY_NAME\"] ?? \"Acme Corp\";\nvar apiKey = Configuration[\"STRIPE_SECRET_KEY\"]\n    ?? throw new InvalidOperationException(\"STRIPE_SECRET_KEY is required\");\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"pre-wired-sinch-sdk-clients","__idx":8},"children":["Pre-wired Sinch SDK clients"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The runtime instantiates Sinch SDK clients for you and attaches them to the context. No credential management in your function."]},{"$$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":"Client"},"children":["Client"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Node"},"children":["Node"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"C#"},"children":["C#"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Env vars required"},"children":["Env vars required"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Voice"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.voice"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Voice"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VOICE_APPLICATION_KEY"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VOICE_APPLICATION_SECRET"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Conversation"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.conversation"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Conversation"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CONVERSATION_APP_ID"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["SMS"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.sms"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Sms"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SMS_SERVICE_PLAN_ID"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Numbers"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.numbers"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Numbers"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ENABLE_NUMBERS_API=true"]}]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Verification (C#)"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["—"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Verification"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VERIFICATION_APPLICATION_ID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["VERIFICATION_APPLICATION_SECRET"]}]}]}]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["All clients require the base Project credentials: ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PROJECT_ID"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PROJECT_ID_API_KEY"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["PROJECT_ID_API_SECRET"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If a required variable is missing, the property is ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["null"]}," — always null-check before using:"]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"if (context.conversation) {\n  await context.conversation.messages.send({ ... });\n}\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"if (Context.Conversation is not null)\n    await Context.Conversation.Messages.Send(...);\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"assets","__idx":9},"children":["Assets"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Private files you ship alongside your code — prompts, JSON data, templates. Keep them in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["assets/"]}," directory and read them with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.assets(filename)"]},". Do ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["not"]}," use ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["fs.readFileSync('./assets/...')"]}," — the deployed artifact structure is different from your dev tree, and the runtime handles the translation for you."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"const greetingText = await context.assets('greetings/en.txt');\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["For public static files (images, CSS, public JSON), use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["public/"]}," directory instead. The runtime serves it at ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["/"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"logger","__idx":10},"children":["Logger"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.log"]}," (Node) and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Context.Logger"]}," (C#) are structured loggers. In production, output is captured, indexed, and streamed via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch functions logs"]},"."]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"typescript","header":{"controls":{"copy":{}}},"source":"context.log?.info('Call received', { callId: data.callid, cli: data.cli });\n","lang":"typescript"},"children":[]},{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"csharp","header":{"controls":{"copy":{}}},"source":"Logger.LogInformation(\"Call received from {Cli}\", data.Cli);\n","lang":"csharp"},"children":[]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["In Node, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["console.log"]}," also works — it's captured the same way as ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.log"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"request-metadata","__idx":11},"children":["Request metadata"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.requestId"]}," — a tracing ID unique to this invocation. Include it in logs and when calling out to other services; it makes cross-service debugging bearable."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.timestamp"]}," — ISO 8601 timestamp when the request entered the runtime."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"related","__idx":12},"children":["Related"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"#"},"children":["Configuration & secrets"]}," — how env vars, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["sinch.json"]}," variables, and secrets flow"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"#"},"children":["Local vs prod"]}," — what changes between dev and deployed environments"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"/docs/functions/reference/function-context"},"children":["Function context reference"]}," — Node + C# side-by-side cheat sheet"]}]}]},"headings":[{"value":"Context object","id":"context-object","depth":1},{"value":"What's in it","id":"whats-in-it","depth":2},{"value":"Cache","id":"cache","depth":2},{"value":"Storage","id":"storage","depth":2},{"value":"Database","id":"database","depth":2},{"value":"Node — sql.js (recommended)","id":"node--sqljs-recommended","depth":3},{"value":"C# — Microsoft.Data.Sqlite","id":"c--microsoftdatasqlite","depth":3},{"value":"Config and variables","id":"config-and-variables","depth":2},{"value":"Pre-wired Sinch SDK clients","id":"pre-wired-sinch-sdk-clients","depth":2},{"value":"Assets","id":"assets","depth":2},{"value":"Logger","id":"logger","depth":2},{"value":"Request metadata","id":"request-metadata","depth":2},{"value":"Related","id":"related","depth":2}],"frontmatter":{"seo":{"title":""}},"lastModified":"2026-04-15T14:23:23.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/docs/functions/concepts/context-object","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}