Skip to content

Upsert a user profile's traits and value score

Writes traits (and optional valueScore) to identified_users — the same table the ingest identify path uses. The response is only returned after the D1 upsert completes (at-least-once, never fire-and-forget).

projectId MUST NOT be supplied in the body — it is always derived from the authenticated API key. Traits are validated by the same sanitizeTraits pipeline as identify (≤ 8 KiB, ≤ 2 nesting levels, dangerous keys rejected).

Auth: X-API-Key with scope profile:write (x-required-scope: profile:write).

Rate limit: 60 req/min per (projectId, IP) — over → 429.

Media typeapplication/json

Profile upsert body. projectId MUST NOT be included — it is derived from the API key.

object
userId
required

Non-empty user/profile ID.

string
traits
required

Trait map (same sanitizeTraits rules as identify — ≤ 8 KiB, ≤ 2 levels, dangerous keys rejected).

object
key
additional properties
any
valueScore

Optional value score.

number | null
Example
json
{
"userId": "uid_456",
"traits": {
"plan": "pro",
"region": "apac"
},
"valueScore": 87.5
}

Profile upserted.

Media typeapplication/json
object
ok
required
boolean

Invalid JSON or invalid payload (bad userId/traits/valueScore, or traits sanitizer rejection).

Media typeapplication/json

400 payload-validation error for the profile endpoint.

object
error
required
string
Allowed values: invalid_json invalid_payload
detail

Human-readable reason (present for invalid_payload).

string
Examples
json
{
"error": "invalid_json"
}

Missing or unresolvable API key.

Media typeapplication/json
object
error
required

Human-readable error message.

string
retryAfter

Seconds to wait before retrying (present on 429/503).

integer
message
string
affectedIndices
Array<integer>
Examples
json
{
"error": "missing_api_key"
}

API key lacks the profile:write scope.

Media typeapplication/json
object
error
required

Human-readable error message.

string
retryAfter

Seconds to wait before retrying (present on 429/503).

integer
message
string
affectedIndices
Array<integer>
Example
json
{
"error": "insufficient_scope"
}

Cross-project key (tenant isolation).

Media typeapplication/json
object
error
required

Human-readable error message.

string
retryAfter

Seconds to wait before retrying (present on 429/503).

integer
message
string
affectedIndices
Array<integer>
Example
json
{
"error": "not_found"
}

Rate limit exceeded (60/min per project+IP).

Media typeapplication/json
object
error
required

Human-readable error message.

string
retryAfter

Seconds to wait before retrying (present on 429/503).

integer
message
string
affectedIndices
Array<integer>
Example
json
{
"error": "rate_limited"
}