Layers
Partner APIAPI referenceProjects

GET /v1/projects/:id

Retrieve a project, including brand context, layers, and approval policy.

View as Markdown
GET/v1/projects/:id
Phase 1stable
Auth
Bearer
Scope
projects:read

Returns the full project record: brand context resolved from ingestion, the layers attached to it, current approval policy, and the state of each ingestion source (GitHub, website, App Store). This is the endpoint to call when your UI needs to render a project detail page.

The project must belong to your key's organization; cross-org reads return 404 NOT_FOUND rather than revealing the project exists.

Path
  • id
    stringrequired
    Project ID.

Example request

curl https://api.layers.com/v1/projects/prj_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39 \
  -H "Authorization: Bearer lp_..."
const project = await layers.projects.get("prj_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39");
project = layers.projects.get("prj_254a4ce1-f4ca-42b1-9e36-17ca45ef3d39")

Response

200OK
{
  "id": "9cb958b5-11b5-4e30-8675-5d075d52da7c",
  "organizationId": "org_2481fa5c-a404-44ed-a561-565392499abc",
  "name": "Acme Coffee iOS",
  "status": "active",
  "customerExternalId": "acme-coffee",
  "timezone": "America/Los_Angeles",
  "primaryLanguage": "en",
  "ownerEmail": "growth@gicgrowth.com",
  "brand": null,
  "brandContext": {
    "appName": "Acme Coffee",
    "appDescription": "Pre-order your neighborhood coffee shop's daily brew.",
    "tagline": "Skip the line, keep the ritual.",
    "audience": "Urban professionals, 25–45",
    "icp": "Mobile-first coffee loyalists",
    "brandVoice": "Friendly, unfussy, a little wry",
    "keywords": ["coffee", "order ahead", "mobile payments"],
    "primaryLanguage": "en",
    "logoUrl": "https://media.layers.com/.../logo.png"
  },
  "platformIosBundleId": "com.acme.coffee",
  "platformAndroidBundleId": "com.acme.coffee.android",
  "platformWebDomain": "acmecoffee.com",
  "ingestState": {
    "github": { "status": "completed", "jobId": "job_01HXA1NHKJ...", "completedAt": "2026-04-10T09:19:33Z" },
    "website": null,
    "appstore": { "status": "completed", "completedAt": "2026-04-10T09:21:02Z" }
  },
  "metadata": null,
  "createdAt": "2026-04-10T09:14:22.000000+00:00",
  "updatedAt": "2026-04-15T17:01:09.000000+00:00"
}

Notes on shape:

  • policy, firstN, pendingCount are flat fields (not nested under approvalPolicy).
  • brand is reserved for the project's brand record; null until a brand is attached.
  • The layers collection is read separately via the project layers endpoint - it is not embedded in this response.
  • platformIosBundleId, platformAndroidBundleId, platformWebDomain are populated by the matching POST /v1/projects/:id/ingest/{appstore,website} jobs. They are read-only on this endpoint — partners cannot set them via PATCH /v1/projects/:id. Downstream features (CAPI configuration, Apple Search Ads, deep-link routing) gate on these values, so the recommended flow is: create project → run ingest job → poll until completed → re-fetch project to read the populated identifiers.

Errors

StatusCodeWhen
401UNAUTHENTICATEDMissing or invalid key.
403FORBIDDEN_SCOPEKey lacks projects:read.
404NOT_FOUNDProject does not exist, or it lives in another organization, or X-Layers-Customer-Id does not match.
422VALIDATION:id is not a UUID. The path parameter is validated pre-flight; non-UUIDs never reach the database.
429RATE_LIMITEDRead budget exhausted.

See also

On this page