{"_id":"@coswic/aipay-sdk","_rev":"7-4bbcee1f02483482ce6f104a7ab8eb41","name":"@coswic/aipay-sdk","dist-tags":{"latest":"0.4.1"},"versions":{"0.2.0":{"name":"@coswic/aipay-sdk","version":"0.2.0","license":"MIT","_id":"@coswic/aipay-sdk@0.2.0","maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"dist":{"shasum":"9a5e7a1a82a0820f40585c1d215b65f2760ff577","tarball":"https://registry.npmjs.org/@coswic/aipay-sdk/-/aipay-sdk-0.2.0.tgz","fileCount":14,"integrity":"sha512-A5knp+4BsCA5xhGqbrqDXWDsKsa1awk4UNFhTtV1qxaps1CQjsMAbHaYSsVDhY4ngJttv437RAoGeEVfuJ66nQ==","signatures":[{"sig":"MEUCIFVL1CQILR7LaFr5LGeTodsPvNxa8ZI8xv1G1oYPfheIAiEAyT9r0hNjRQ1ooOPVaHR1bQl2s8fWxlLS5ISXN445Mqw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":54191},"main":"./dist/index.js","type":"module","_from":"file:/tmp/claude-1000/-home-ubuntu/10df7663-8de2-44db-abff-8d7f6423510e/scratchpad/coswic-aipay-sdk-0.2.0.tgz","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"patrick_coswic","email":"patrick@coswic.ai"},"_resolved":"/tmp/claude-1000/-home-ubuntu/10df7663-8de2-44db-abff-8d7f6423510e/scratchpad/coswic-aipay-sdk-0.2.0.tgz","_integrity":"sha512-A5knp+4BsCA5xhGqbrqDXWDsKsa1awk4UNFhTtV1qxaps1CQjsMAbHaYSsVDhY4ngJttv437RAoGeEVfuJ66nQ==","deprecated":"Broken package exports (pointed at src/index.ts, not shipped) — install 0.3.1 or later.","_npmVersion":"10.9.3","description":"AIPay TypeScript SDK — Sign in with AIPay（OAuth PKCE）＋ AI chat（計量扣款、串流、重放）client。零依賴，Node 20+ 與現代瀏覽器皆可用。","directories":{},"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/aipay-sdk_0.2.0_1787635352117_0.9573431358367539","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@coswic/aipay-sdk","version":"0.3.0","keywords":["aipay","ai","billing","oauth","pkce","sdk","llm","streaming"],"license":"MIT","_id":"@coswic/aipay-sdk@0.3.0","maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"dist":{"shasum":"472664f59ec5d168482c6aba92cf5bf0bff11b96","tarball":"https://registry.npmjs.org/@coswic/aipay-sdk/-/aipay-sdk-0.3.0.tgz","fileCount":15,"integrity":"sha512-HmFD4HNk7CigYSy0M0yH0WHWEycCTSXMH2PvW+HGW/JengUCdIgYfm55/pplVLihNC6cFvRXHUvnFf5d2Jmp/g==","signatures":[{"sig":"MEUCIQCqcSJhqCG/UWiRUaAz9Oe5YlYQvz+qSahmbgShVu8M4wIgAnE9wXo1mjTwwNPfaGhYaV4eeoSQGyMGklFjffYw9d0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":59477},"type":"module","exports":{".":"./src/index.ts"},"gitHead":"60fb14342600a5f1dd13f1d260f512e463b6b5a6","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"patrick_coswic","email":"patrick@coswic.ai"},"deprecated":"Broken package exports (pointed at src/index.ts, not shipped) — install 0.3.1 or later.","_npmVersion":"10.9.3","description":"AIPay TypeScript SDK — Sign in with AIPay (OAuth PKCE) + metered AI chat client (streaming, idempotent retries, replay). Zero dependencies; Node 20+ and modern browsers.","directories":{},"_nodeVersion":"22.20.0","publishConfig":{"main":"./dist/index.js","types":"./dist/index.d.ts","access":"public","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}}},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/aipay-sdk_0.3.0_1788319926186_0.9678579312911311","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@coswic/aipay-sdk","version":"0.3.1","keywords":["aipay","ai","billing","oauth","pkce","sdk","llm","streaming"],"license":"MIT","_id":"@coswic/aipay-sdk@0.3.1","maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"dist":{"shasum":"657417673a7422ffb573383a75dc622807af6bbd","tarball":"https://registry.npmjs.org/@coswic/aipay-sdk/-/aipay-sdk-0.3.1.tgz","fileCount":15,"integrity":"sha512-/1pHRXS6V6LPi4Cdus5Oow3CnsNHJHRJC6Ht6jkLvy+tL0lBkOA4IT6fe623T3ubNhcXFTJhXqUQqQll9JY4bg==","signatures":[{"sig":"MEUCIQDDkHL6xyKB1sUgqyI8TdFtY26V3hA31GH+x2WH6LkD5gIgD/GrYOOU03nVwdkTxA9MVACTBIBUSUpbIseNqmeRbsE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60201},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"patrick_coswic","email":"patrick@coswic.ai"},"description":"AIPay TypeScript SDK — Sign in with AIPay (OAuth PKCE) + metered AI chat client (streaming, idempotent retries, replay). Zero dependencies; Node 20+ and modern browsers.","directories":{},"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/aipay-sdk_0.3.1_1788623533793_0.15285852528618316","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@coswic/aipay-sdk","version":"0.3.2","keywords":["aipay","ai","billing","oauth","pkce","sdk","llm","streaming"],"license":"MIT","_id":"@coswic/aipay-sdk@0.3.2","maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"dist":{"shasum":"b972f01db702c76cd9eb9d17136e763a09a157e6","tarball":"https://registry.npmjs.org/@coswic/aipay-sdk/-/aipay-sdk-0.3.2.tgz","fileCount":15,"integrity":"sha512-iCQyt+J8sfdAFHeJtc5Jg197G5ut6cNSqs9MlePZgcvgAzV05GD95y25GfUz/+TGjU+mnJiMvm8e1+gulbdQ/w==","signatures":[{"sig":"MEQCIDYGnd2Ywgry3ANk1JHcsgQAg7zPnRL7f8Og4BeX2R0iAiA+edAkIwmJTZFBkMTlev4TNpRYXu2zwHhxBFYsF7/9Lw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":60292},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"patrick_coswic","email":"patrick@coswic.ai"},"description":"AIPay TypeScript SDK — Sign in with AIPay (OAuth PKCE) + metered AI chat client (streaming, idempotent retries, replay). Zero dependencies; Node 20+ and modern browsers.","directories":{},"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/aipay-sdk_0.3.2_1788849232536_0.4268398831631832","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@coswic/aipay-sdk","version":"0.4.0","keywords":["aipay","ai","billing","oauth","pkce","sdk","llm","streaming"],"license":"MIT","_id":"@coswic/aipay-sdk@0.4.0","maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"homepage":"https://ai-pay.coswic.ai/docs?lang=en","dist":{"shasum":"0b84bd43eb92ff0671e17bfcf66bf7c44886d8a1","tarball":"https://registry.npmjs.org/@coswic/aipay-sdk/-/aipay-sdk-0.4.0.tgz","fileCount":18,"integrity":"sha512-J5K6oWmHej/0JU2N/avT6SvVeqI6z9LNI+IVXU2/uLppZY5U7gjjFqi8szmbczcx5VmZevRyr3py0ac6i5e5NQ==","signatures":[{"sig":"MEUCIGdFYyCwLexM9gt2n3nkse/pfSWJTctw3KcdHYeMtHYoAiEAvlBY5elJzPtUrQuixi7FY8a0ovJ6h+fY+c/MgCZUSHI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIHHSld5KJ3EXBKSTOzHzYJlE0epUOAewMZPGJ9A7FQHlAiBbDC5Qpb9rSmY43ZGpvBwlfXo2KrmbGDdavyPqjB25pA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":69411},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"_npmUser":{"name":"patrick_coswic","email":"patrick@coswic.ai"},"description":"AIPay TypeScript SDK — OAuth PKCE, metered AI chat, and Live model discovery and receipts. Zero dependencies; Node 20+ and modern browsers.","directories":{},"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/aipay-sdk_0.4.0_1790349283207_0.7864086044959724","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"_id":"@coswic/aipay-sdk@0.4.1","dist":{"shasum":"8a4a1c7565651a88644a0ec965075e75f120c3e0","tarball":"https://registry.npmjs.org/@coswic/aipay-sdk/-/aipay-sdk-0.4.1.tgz","fileCount":18,"integrity":"sha512-Jbnb4NOTwc9oEaiXHfAWRpSOXucwFQPwq/sxztpo+UH26NmEuJx9QeSsSOr7CCKe8doyY9Deok9/nayQ5ZdwNA==","signatures":[{"sig":"MEQCIHoVXMBLGPCoiZgtl6txvuHd4QuL5IVj6mXSzTgjrODBAiAuraiJbw3smY0exH1bKJQjUjksPgyYj0HJVxX8fienaQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIA4z3JKqMcvD6/SHEHsy0Heo34sg+5xBZjciww1oGKdVAiBazw55IVCo4aY0wVJAhYpHHxRzZtkIP9fxPWE/wYZJVQ=="}],"unpackedSize":70727},"main":"./dist/index.js","name":"@coswic/aipay-sdk","type":"module","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"license":"MIT","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","typecheck":"tsc --noEmit"},"version":"0.4.1","_npmUser":{"name":"patrick_coswic","email":"patrick@coswic.ai"},"homepage":"https://ai-pay.coswic.ai/docs?lang=en","keywords":["aipay","ai","billing","oauth","pkce","sdk","llm","streaming"],"description":"AIPay TypeScript SDK — OAuth PKCE, metered AI chat, and Live model discovery and receipts. Zero dependencies; Node 20+ and modern browsers.","directories":{},"maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"_nodeVersion":"22.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aipay-sdk_0.4.1_1790752467432_0.5612357195036097"}}},"time":{"created":"2026-08-25T05:22:31.916Z","modified":"2026-09-30T07:14:27.704Z","0.2.0":"2026-08-25T05:22:32.265Z","0.3.0":"2026-09-02T03:32:06.331Z","0.3.1":"2026-09-05T15:52:13.930Z","0.3.2":"2026-09-08T06:33:52.735Z","0.4.0":"2026-09-25T15:14:43.299Z","0.4.1":"2026-09-30T07:14:27.528Z"},"license":"MIT","homepage":"https://ai-pay.coswic.ai/docs?lang=en","keywords":["aipay","ai","billing","oauth","pkce","sdk","llm","streaming"],"description":"AIPay TypeScript SDK — OAuth PKCE, metered AI chat, and Live model discovery and receipts. Zero dependencies; Node 20+ and modern browsers.","maintainers":[{"name":"patrick_coswic","email":"patrick@coswic.ai"}],"readme":"# @coswic/aipay-sdk — TypeScript SDK\n\n> **Free beta.** AI-Pay's production environment is in a free beta: signing in with a Google account for the first time creates an account while self sign-up seats last; once they are full, only invited emails can create an account. Your users create their AI-Pay account the same way the first time they sign in through your app, and, unless invited, take a self sign-up seat. Production does not accept top-ups at the moment. Create your app in the Console, then integrate with its public client ID and the standard OAuth flow described below.\n\n> Developer toolkit for integrating **AIPay** (spec §SDK). **One codebase for server and\n> browser** — WebCrypto + `fetch` only (ADR-013 deployment-neutral: the AI endpoint and the\n> token endpoint ship CORS, so serverless apps can run the whole flow in-page).\n> Browser rules: **do not request `offline_access`** (a refresh token is a long-lived\n> credential and does not belong in a browser); keep the access token in memory and let it\n> expire naturally after 15 minutes; worst case is capped by the user's own spending limit\n> plus instant revocation.\n\n## Documentation and links\n\n- **Developer guide** (start here): https://ai-pay.coswic.ai/docs?lang=en — quickstart, OAuth scopes, request rules, receipts, retry discipline, error codes. Markdown edition for coding agents: https://ai-pay.coswic.ai/docs.md?lang=en\n- **Models and prices**: https://ai-pay.coswic.ai/models?lang=en (the same catalog billing uses; JSON at `GET /v1/models`)\n- **API contract**: https://ai-pay.coswic.ai/openapi.yaml (OpenAPI 3.1, generated from the code)\n- **Product overview and what is open today**: https://ai-pay.coswic.ai/about?lang=en\n- **Companion CLI**: [`@coswic/aipay`](https://www.npmjs.com/package/@coswic/aipay) — `aipay init` scaffolds the sign-in routes for your framework and writes `aipay-agent.md`; `aipay test` runs a real sign-in plus one metered request and prints the receipt.\n- **Terms**: https://ai-pay.coswic.ai/terms?lang=en · **Privacy**: https://ai-pay.coswic.ai/privacy?lang=en\n\nSeats, the first sign-in credit and what is open today are on the product overview above. The examples below use placeholder hosts (`https://api.aipay.example`); use the API base and authorization server of the environment you integrate with — the developer guide fetched from that environment has both filled in.\n\n## 1. Sign in with AIPay (getting the user's authorization)\n\n```ts\nimport { createConnectUrl, handleCallback, refreshAccessToken } from '@coswic/aipay-sdk'\n\nconst cfg = {\n  hydraPublicUrl: 'https://auth.aipay.example',\n  clientId: '<client_id returned by POST /v1/developer/apps>',\n  redirectUri: 'https://yourapp.example/aipay/callback',\n  // Default scopes exclude offline_access (least privilege). This example calls\n  // refreshAccessToken later (server app, tokens kept in a server session), so we\n  // opt in explicitly:\n  scopes: ['openid', 'email', 'ai.chat.create', 'wallet.charge', 'offline_access'],\n}\n\n// 1. Build the authorization URL (PKCE S256 + state, generated for you) — store\n//    { state, codeVerifier } in your session (browser: sessionStorage).\nconst { url, state, codeVerifier } = await createConnectUrl(cfg)\n// 2. The user signs in at AIPay, sets a spending limit, consents → lands on your\n//    callback (?code=…&state=…).\n// 3. In the callback, handleCallback does \"check error → verify state → exchange code\"\n//    in one step. Don't hand-roll state verification (easy to skip; skipping it is a\n//    CSRF / code-injection surface). A user pressing \"deny\", or a lost session, throws\n//    a ConnectError with a clear message.\nconst tokens = await handleCallback(cfg, callbackUrl, { state, codeVerifier })\n// tokens.accessToken (15 min), tokens.refreshToken (rotating — store the new one,\n// the old one is invalidated).\nconst fresh = await refreshAccessToken(cfg, tokens.refreshToken)\n```\n\n> The low-level `exchangeCode(cfg, { code, codeVerifier })` is still available for\n> custom flows, but then verifying `state` first is on you; for normal integrations\n> always use `handleCallback`.\n\n## 2. Calling models (the bill travels with the response)\n\n```ts\nimport { AIPayClient } from '@coswic/aipay-sdk'\n\nconst client = new AIPayClient({\n  baseUrl: 'https://api.aipay.example',\n  accessToken: tokens.accessToken,\n})\n\nconst res = await client.chat.completions.create({\n  model: 'openai/gpt-4o-mini',\n  messages: [{ role: 'user', content: '…' }],\n  max_tokens: 200,\n})\nres.choices[0].message.content\nres.aipay.cost_uusd     // what this request actually charged (integer µUSD string) —\n                        // response in hand = the charge is booked\nres.aipay.breakdown     // three-way split: provider cost / platform fee / your margin\n\n// Streaming\nconst stream = await client.chat.completions.create({ model, messages, stream: true })\nfor await (const ev of stream) {\n  if (ev.type === 'delta') process.stdout.write(ev.content)\n  if (ev.type === 'receipt') console.log('\\ncharged', ev.aipay.cost_uusd, 'µUSD')\n  if (ev.type === 'replay') { /* same-key resend of an already-settled request = the\n                                 original returned once */ }\n}\n```\n\n## 3. Built-in conventions (spec §SDK; each can be turned off)\n\n- **Idempotency-Key generated for you** (UUID); every retry — including the SDK's own\n  retries — reuses the same key, so a lost response can never become a second charge.\n  To fetch the same result again later, resend with your own `idempotencyKey` +\n  `replayKey` pair.\n- **Replay-Key is opt-in, off by default** (ADR-007): `new AIPayClient({ autoReplayKey:\n  true })` generates one per request (CSPRNG 32 bytes, `generateReplayKey()`), or pass\n  `replayKey` per call. With it, the response is encrypted into a capsule and stored\n  atomically with settlement — resending the same key pair returns the **original\n  content** (TTL 15 minutes). Without it (default), a resend returns the receipt only\n  (amount charged, usage; `choices` empty). It defaults to off because every Replay-Key\n  costs the server a deliberately expensive scrypt key derivation — callers who keep\n  their own copy of the response don't need the capability.\n- **Retries follow the flag, not the HTTP status**: the SDK auto-retries only codes\n  mapped to `ProviderError` — `provider_unavailable` / `provider_timeout` /\n  `catalog_unavailable` / `service_overloaded` (v0.3.0: load shedding; the server\n  guarantees nothing was executed and asks for a same-key retry, and the SDK honors\n  the `Retry-After` header it sends) — and only with `details.retryable:true`\n  (server-guaranteed unexecuted, zero charge; a 504 during the estimate phase\n  qualifies too), plus 429 and network errors — same key, exponential backoff\n  (`maxRetries` default 2). `pricing_stale` / `model_price_unavailable` stay with the\n  generic `AIPayApiError` and are **not** auto-retried — switching models is a real\n  alternative there, so that decision is yours. **`outcome:'unknown'` (e.g.\n  `usage_unknown`) is never auto-retried** (money may already be settled) — on\n  `ProviderError.outcomeUnknown`, you decide when to resend the same key to learn the\n  final outcome.\n- **422 budget_exceeded**: by default the SDK shrinks `max_tokens` from\n  `max_affordable_uusd` and retries once — with a **new** key (422 = never executed;\n  the payload changed, so reusing the old key would 409). Disable with\n  `shrinkOnBudgetExceeded: false`.\n\n## 4. Error taxonomy\n\nEverything extends `AIPayApiError` (code / message / request_id / details preserved\nverbatim): `InsufficientBalanceError` (402, `shortfallUUsd`), `BudgetExceededError`\n(422, `which` / `limitUUsd` / `maxAffordableUUsd`), `AuthorizationError` (403 —\nrevoked / paused / circuit-broken / re-consent required), `IdempotencyConflictError`\n(409, `reason`), `RateLimitedError` (429), `ProviderError` (502/503/504,\n`retryable` / `outcomeUnknown` / `charged`).\n\n## Out of scope (added when the platform side exists, AGENTS §26)\n\n`webhooks.verify()` (developer webhook outbox not yet implemented), Python SDK,\nbrowser-bundle build.\n\n## Tests\n\n`pnpm --filter @coswic/aipay-sdk test` — contract tests with a mocked `fetch`:\nverifiable PKCE, key-reuse/replacement matrix, error taxonomy, budget-shrink math,\nretry/Retry-After semantics, SSE parsing. The full real-environment chain (real Hydra +\nreal model) was last verified end-to-end against the live stack (see dev-log).\n\n## Live discovery and receipts (0.4.0)\n\nLive requires explicit `ai.live.create wallet.charge` consent; existing chat tokens do\nnot gain Live access. Preserve `ai.chat.create` in the new scope request if the App\nstill needs chat. Older registered Apps may need their OAuth client updated through\nthe existing Console redirect-URI update flow before requesting Live.\n\n```ts\nconst offerings = await client.live.models.list()\nconst receipt = await client.live.sessions.retrieve(savedSessionId)\n// cost_uusd is an integer µUSD string or null. Null is pending/unknown, never zero.\n```\n\nThese read-only methods do not cache, automatically retry, or start a billable\nsession. WebSocket creation currently requires a server client that can send the\nAuthorization and Idempotency-Key headers. Do not put tokens in WebSocket URLs.\nA receipt can briefly lag the settlement event while the accounting projection\ncatches up; read again within an application-defined bound instead of starting a\nnew session. `unknown` is not proof of zero supplier cost.\n\nSee the Live onboarding guide (`docs/api/live-onboarding.md` in the source repository; not yet part of the public developer docs) for renewed consent,\nserver transport, receipt/revocation handling, and the non-billable launch probe.\nLive discovery and receipt methods require SDK 0.4.0 or later. Available offerings\nand production access depend on the server configuration and your App’s consent.\n","readmeFilename":""}