PATCH /v1/projects/:projectId/sdk-apps/:appId
Update SDK-app config, enable CAPI for a platform, or rotate the API key.
/v1/projects/:projectId/sdk-apps/:appId- Auth
- Bearer
- Scope
- projects:write
Patch any user-editable field on an SDK app, enable or disable CAPI forwarding per ad platform, or force a key rotation. Omitted fields stay unchanged.
Passing rotateKey: true is the only case where the response includes a plaintext apiKey — the old key is invalidated immediately. Clients using the old key start receiving 401 on the ingest endpoint within seconds.
Enabling CAPI requires two things already stored on the project layer: the pixel_id for the ad platform and a vault-encrypted access token. Set these up via the ad-accounts OAuth flow before flipping capi.{platform}.enabled here.
projectIdstringrequiredProject ID.appIdstringrequiredSDK app ID.
namestringoptional1–128 chars.bundleIdstringoptionaliOS builds only.androidPackagestringoptionalAndroid builds only.webDomainstringoptionalWeb builds only.capiobjectoptionalPer-platform CAPI toggles. Shape: { meta?: { enabled }, tiktok?: { enabled }, apple?: { enabled } }.rotateKeybooleanoptionalIf true, create a fresh API key and invalidate the current one. The new key is returned once.
Example request
curl -X PATCH "https://api.layers.com/v1/projects/9cb958b5-11b5-4e30-8675-5d075d52da7c/sdk-apps/app_8ffb9410eb0eb848264f8a65" \
-H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..." \
-H "Content-Type: application/json" \
-d '{
"capi": { "meta": { "enabled": true } },
"rotateKey": true
}'const app = await layers.sdkApps.update(
"9cb958b5-11b5-4e30-8675-5d075d52da7c",
"app_8ffb9410eb0eb848264f8a65",
{
capi: { meta: { enabled: true } },
rotateKey: true,
}
);
// Store app.apiKey — the previous key is dead.app = layers.sdk_apps.update(
project_id="9cb958b5-11b5-4e30-8675-5d075d52da7c",
app_id="app_8ffb9410eb0eb848264f8a65",
capi={"meta": {"enabled": True}},
rotate_key=True,
)
# Store app["apiKey"] — the previous key is dead.Response
{
"appId": "app_8ffb9410eb0eb848264f8a65",
"name": "Acme Coffee iOS",
"platform": "ios",
"bundleId": "com.acmecoffee.ios",
"androidPackage": null,
"webDomain": null,
"ingestEndpoint": "https://in.layers.com/l/events",
"capi": {
"meta": { "enabled": true }
},
"createdAt": "2026-04-18T19:25:22Z",
"lastRotatedAt": "2026-04-18T19:31:42Z",
"lastEventAt": "2026-04-18T19:42:11Z",
"apiKey": "sk_app_3mNp...x9F"
}The response body is the full SDK-app shape (same as GET /v1/projects/:projectId/sdk-apps/:appId) plus apiKey when rotateKey: true was set. capi only carries entries for platforms you've toggled — pixel/lastForwardAt fill in once the ad-account OAuth flow has stored credentials and the relay has forwarded an event.
Errors
| Status | Code | When |
|---|---|---|
| 422 | VALIDATION | Unknown field, platform-identifier mismatch (e.g. passing androidPackage on an iOS app). |
| 401 | UNAUTHENTICATED | Missing or invalid key. |
| 403 | FORBIDDEN_SCOPE | Key lacks projects:write. |
| 404 | NOT_FOUND | Project or SDK app does not exist. |
| 409 | CONFLICT | CAPI enable requested for a platform without a pixel_id or vault token configured. Connect the ad account first. |
| 429 | RATE_LIMITED | Write budget exhausted. |
See also
GET /v1/projects/:projectId/sdk-apps/:appId— read current state- Ad accounts OAuth — prerequisite for CAPI enable