Layers
Partner APIAPI referenceSDK apps

PATCH /v1/projects/:projectId/sdk-apps/:appId

Update SDK-app config, enable CAPI for a platform, or rotate the API key.

View as Markdown
PATCH/v1/projects/:projectId/sdk-apps/:appId
Phase 1stable
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.

Path
  • projectId
    stringrequired
    Project ID.
  • appId
    stringrequired
    SDK app ID.
Body
  • name
    stringoptional
    1–128 chars.
  • bundleId
    stringoptional
    iOS builds only.
  • androidPackage
    stringoptional
    Android builds only.
  • webDomain
    stringoptional
    Web builds only.
  • capi
    objectoptional
    Per-platform CAPI toggles. Shape: { meta?: { enabled }, tiktok?: { enabled }, apple?: { enabled } }.
  • rotateKey
    booleanoptional
    If 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

200OK
{
  "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

StatusCodeWhen
422VALIDATIONUnknown field, platform-identifier mismatch (e.g. passing androidPackage on an iOS app).
401UNAUTHENTICATEDMissing or invalid key.
403FORBIDDEN_SCOPEKey lacks projects:write.
404NOT_FOUNDProject or SDK app does not exist.
409CONFLICTCAPI enable requested for a platform without a pixel_id or vault token configured. Connect the ad account first.
429RATE_LIMITEDWrite budget exhausted.

See also

On this page