Skip to main content
POST
/
api
/
context
/
regenerate
Regenerate user context
curl --request POST \
  --url https://app.puffle.ai/api/context/regenerate \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "website": "<string>",
  "linkedinUrl": "<string>",
  "companyLinkedinUrl": "<string>",
  "freeformContext": "<string>"
}
'
{
  "success": true,
  "runId": "run_a1b2c3d4e5f6",
  "lastContextRegeneratedAt": "2026-04-22T10:15:00.000Z"
}

Overview

Kicks off the context-regenerate Trigger.dev task for the authenticated user. Given a website and/or linkedinUrl, the task re-crawls and re-runs the same Sonnet generations the initial onboarding uses, updating company_context, market_context, and user_context on the user’s user_profiles row. freeformContext, when supplied, is written synchronously to user_profiles.extra_context.freeform before the task is dispatched — it does not require a scrape and takes effect immediately. Rate-limited to one call per 24 hours per user. A second call inside the window returns 429 with a nextAvailableAt ISO timestamp.
Facet note: the GET /api/context endpoint itself is owned by the Core facet. This operation lives under Onboarding because it drives the same scrape-and-generate flow as start-onboarding-scrape. If an agent wants to read the current context, it should call GET /api/context (Core); if it wants to refresh the context, it should call this endpoint.

AI agent notes

When to call: the human explicitly asks to refresh context (rebrand, website URL change, updated positioning notes). Do not call proactively.Before calling:
  1. Read GET /api/context so you know what the current context looks like — helps you explain the delta to the human afterwards.
  2. Confirm with the human that you have the right website / linkedinUrl / freeformContext. Wrong inputs will silently pollute context and the only way to recover is to wait 24 h and redo it.
After calling:
  1. The response stamps lastContextRegeneratedAt. Keep it — a second call before that timestamp plus 24 h returns 429.
  2. The scrape runs in the background. Poll GET /api/context every 10 to 30 seconds until the context reflects the new inputs. There is no dedicated status endpoint for this task.
On 429: surface nextAvailableAt to the human; do not retry.
See also: Check onboarding status · Start the onboarding scrape · Agent Playbook.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Body

application/json

All fields are optional at the schema level, but at least one of website or linkedinUrl must be supplied or the call returns 400.

website
string

Company website URL to re-scrape for updated company_context and market_context. At least one of website or linkedinUrl is required.

linkedinUrl
string

Personal LinkedIn profile URL. Used to refresh user_context (tone, positioning, role). At least one of website or linkedinUrl is required.

companyLinkedinUrl
string

Company LinkedIn page URL. Used as a supplementary source for company_context.

freeformContext
string

Free-form text the user wants blended into context (e.g. positioning notes, ICP overrides). Written to extra_context.freeform synchronously before the task dispatches — does not require a scrape.

Response

Regeneration task dispatched, rate limit stamped.

Dispatched. Context writes happen inside the Trigger task; there is no dedicated status endpoint — re-read GET /api/context after 30–60 s.

success
enum<boolean>
required
Available options:
true
runId
string
required

Trigger.dev run identifier for the context-regenerate task. Keep for support.

lastContextRegeneratedAt
string<date-time>
required

ISO-8601 timestamp stamped on the user profile. Enforces the 1-per-24-hour rate limit.

Pattern: ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$