Layers
Partner APIConcepts

Influencers

AI brand ambassadors that drive your customer's UGC content. Created automatically on project provision; customizable per-project.

View as Markdown

An influencer is a brand-ambassador persona attached to a project. It has a look, a voice, a speaking style, a sense of humor, and a set of content themes. When you generate UGC-style content, the influencer is what the hook, the caption, and the narrative speak as.

Influencers aren't real people. They're synthetic personas, rendered consistently across generations so a customer's feed reads like one creator instead of a pile of LLM output. One project can have many; most projects ship with one auto-created at onboarding and add more over time.

Where they come from

Two paths:

  1. Auto-created at project provision. When brand ingestion completes (GitHub, website, or App Store), Layers seeds the project with an initial influencer whose personality is derived from brand context — voice, target audience, language. You don't have to do anything for this to happen.
  2. Created on demand. POST /v1/projects/:projectId/influencers creates an influencer row. For simple cases you pass only name; the schema accepts the full persona (archetype, primary language, voice profile, personality fields) as optional fields on the same call.

Schema

An influencer row exposes identity fields (influencerId, name, gender, ageRange, status), a personality object describing voice, and a referenceImages[] array describing the appearance anchor. Full shape:

{
  "influencerId": "inf_01HX9Y6K7EJ4T2ABCDEF",
  "projectId": "254a4ce1-f4ca-42b1-9e36-17ca45ef3d39",
  "name": "Nova",
  "gender": "nonbinary",
  "ageRange": "25-34",
  "status": "ready",
  "thumbnailUrl": "https://media.layers.com/inf/thumb.jpg",
  "personality": {
    "traits": ["earnest", "thorough"],
    "tone": "conversational",
    "humor": "deadpan",
    "formality": "casual",
    "values": ["transparency", "craft"],
    "interests": ["productivity", "tools-I-use"],
    "speakingStyle": "direct",
    "catchphrases": ["Ship it."]
  },
  "referenceImages": [
    {
      "assetId": "med_01HX9Y6K7EJ4T2ABCDEF",
      "url": "https://media.layers.com/...",
      "thumbnailUrl": "https://media.layers.com/...",
      "addedAt": "2026-04-18T12:04:11.000Z"
    }
  ],
  "createdAt": "2026-04-18T12:04:11.000Z",
  "updatedAt": "2026-04-18T12:04:11.000Z"
}

Status values: draft | pending | training | ready | failed. Gender values: male | female | nonbinary | unspecified.

The personality block is consumed by the narrative generator during UGC content generation. It doesn't affect organic engagement logic, ad bidding, or approval scoring — purely narrative.

Changing personality fields doesn't retroactively regenerate existing content. It only affects new generations that reference this influencer after the patch lands.

Cloning

POST /v1/influencers/:influencerId/clone
{
  "name": "Nova (B variant)",
  "newInfluencerId": "inf_01HX9Y6K7EJ4T2NOVAB",
  "overrides": {
    "personality": { "humorStyle": "dry-witty" }
  }
}
202
{
  "jobId": "job_01HX9Y6K7EJ4T2ABCDEF01234",
  "kind": "influencer_clone",
  "status": "running",
  "influencerId": "inf_01HX9Y6K7EJ4T2NOVAB"
}

Clone is async; a render job produces fresh reference images using the source influencer's appearance as an anchor, then applies any overrides before the new row lands in status: ready.

Selecting an influencer for content

When you generate content, the brief can carry an influencerId:

{
  "brief": {
    "targetPlatforms": ["tiktok", "instagram"],
    "influencerId": "inf_01HX9Y6K7EJ4T2ABCDEF",
    "themeTags": ["launch", "feature-spotlight"]
  }
}

If you don't pass one, the generator picks the project's primary influencer. If you want a round-robin across multiple influencers on a single project, do the selection in your own code before calling — the API doesn't rotate for you.

Lifecycle

  • PATCH /v1/influencers/:influencerId updates personality, name, or gender / age-range.
  • DELETE /v1/influencers/:influencerId soft-deletes. Body is optional { "reason": "..." } which is persisted on the deleted row for audit. The response is { "influencerId", "status": "deleted", "deletedAt" }. Deleted influencers still appear on any historical content that used them; they just can't be selected for new generations.
  • POST /v1/influencers/:influencerId/reference-images binds media-library assets as references. Body: { "assetIds": ["med_..."] } — array-of-ids. The response echoes the full referenceImages[] list on the influencer. Assets that don't resolve are silently dropped; the response only contains resolved ones.

On this page