Layers
Partner APIAPI referenceSDK apps

POST /v1/projects/:projectId/sdk-apps

Provision an SDK app for a project. Returns the ingest endpoint and API key once.

View as Markdown
POST/v1/projects/:projectId/sdk-apps
Phase 1stableidempotent
Auth
Bearer
Scope
projects:write

Creates an SDK app and creates its ingest API key. An SDK app is the binding between a platform build (iOS bundle, Android package, web domain) and the Layers event pipeline — once installed, the client SDK sends events to in.layers.com/l/events authenticated with the key returned here.

The API key in the response is shown once. Store it immediately — Layers does not display it again. Rotation is available via PATCH /v1/projects/:projectId/sdk-apps/:appId.

When the GitHub ingest flow POST /v1/projects/:id/ingest/github completes, it already provisioned an SDK app for you — use this endpoint only when the user is installing the SDK by hand, via a second platform, or when you need a new key.

Path
  • projectId
    stringrequired
    Project ID.
Headers
  • Idempotency-Key
    string (UUID)optional
    Replays within 24h.
Body
  • appId
    stringoptional
    Partner-created SDK app ID. If omitted, the server generates one.
  • name
    stringrequired
    Human-readable app name, 1–128 chars.
  • platform
    stringrequired
    Target platform.
    One of: ios, android, web, react-native, flutter, expo
  • bundleId
    stringoptional
    iOS bundle identifier, required when platform is ios.
  • androidPackage
    stringoptional
    Android package name, required when platform is android.
  • webDomain
    stringoptional
    Apex domain for web installs, required when platform is web.

Example request

curl https://api.layers.com/v1/projects/9cb958b5-11b5-4e30-8675-5d075d52da7c/sdk-apps \
  -H "Authorization: Bearer lp_live_01HX9Y6K7EJ4T2_4QZpN..." \
  -H "Idempotency-Key: 2f0e1c88-4b1d-4ac1-bc0a-5e9f6d8a7b10" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Coffee iOS",
    "platform": "ios",
    "bundleId": "com.acmecoffee.ios"
  }'
const app = await layers.sdkApps.create(
  "9cb958b5-11b5-4e30-8675-5d075d52da7c",
  {
    name: "Acme Coffee iOS",
    platform: "ios",
    bundleId: "com.acmecoffee.ios",
  },
  { idempotencyKey: crypto.randomUUID() }
);
// Store app.apiKey now — it won't be shown again.
app = layers.sdk_apps.create(
    project_id="9cb958b5-11b5-4e30-8675-5d075d52da7c",
    name="Acme Coffee iOS",
    platform="ios",
    bundle_id="com.acmecoffee.ios",
    idempotency_key=str(uuid.uuid4()),
)
# Store app["apiKey"] now — it won't be shown again.

Response

201Created
{
  "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": {},
  "createdAt": "2026-04-18T19:25:22Z",
  "lastRotatedAt": "2026-04-18T19:25:22Z",
  "lastEventAt": null,
  "apiKey": "sk_app_8eRq...k2P"
}

capi is an empty object until you enable per-platform forwarding via PATCH. lastRotatedAt is set to createdAt on first creation.

apiKey is returned only on creation and rotation. If you lose it, rotate via PATCH to create a new one — the previous key is invalidated immediately.

Errors

StatusCodeWhen
422VALIDATION:projectId is not a UUID, platform unknown, or missing platform-specific identifier (bundleId, androidPackage, webDomain).
401UNAUTHENTICATEDMissing or invalid key.
403FORBIDDEN_SCOPEKey lacks projects:write.
404NOT_FOUNDProject does not exist in the key's organization.
409CONFLICTSDK app with the supplied appId or (platform, bundleId/androidPackage/webDomain) already exists.
429RATE_LIMITEDWrite budget exhausted.

See also

On this page