GoldKit indexes the camera roll on the user's device and keeps a profile of the user up to date in the background. Your product reads that profile through a single API. Photos never reach your servers, and they never reach ours either.
Gold runs alongside your app rather than inside your request path. Indexing happens in the background on the user's device, so nothing the user does ever waits on it. When you want context, your servers call a REST endpoint and get back the part of the profile that matches the purpose you registered.
Your app embeds GoldKit. The SDK presents Gold's consent sheet and requests photo access under your app's identity.
GoldKit indexes on-device. It groups the roll into events, throws out near-duplicates, and analyzes a representative photo or two from each event. The photos themselves stay on the phone.
A usable profile forms in the first session. Gold indexes a diverse sample of the roll first, then works backward through older history. New photos get folded in as they are taken.
Your servers read scoped context. One GET request returns interests, traits, and rhythms for the scope you're personalizing, plus coverage metadata that tells you how much history is behind it.
Add GoldKit with Swift Package Manager:
// Package.swift, or Xcode → Add Package Dependency .package(url: "https://github.com/gold-context/goldkit-swift", from: "0.9.2")
The repository is private. Access comes with your partner key.
Configure, request access, and watch coverage. The consent sheet is Gold's own UI. It explains to the user what leaves the device before asking for photo permission.
import GoldKit // 1. Configure once, at launch Gold.configure(apiKey: "gk_live_9x…", user: currentUserID) // 2. Present the consent sheet. Indexing starts on grant. let grant = try await Gold.requestAccess(from: viewController) // 3. Coverage moves warming → usable → backfilled for await coverage in Gold.coverageUpdates { if coverage.state == .usable { enablePersonalization() } }
That's all the client code there is. You don't schedule indexing: the SDK paces itself around battery, temperature, and whether your app is in the foreground. Everything from here on is server-side.
To request API keys, request a demo.
Android (Kotlin) is in development. The server API is identical across platforms.
Call this from your servers with your secret key. Responses are scoped: you name the area you're personalizing and get back only that part of the profile. Profiles are precomputed, so the endpoint is cheap enough to sit in an interactive request path.
curl "https://api.embedgold.com/v1/users/usr_8f3k2/context?scope=dining" \ -H "Authorization: Bearer $GOLD_SECRET_KEY"
{
"user": "usr_8f3k2",
"scope": "dining",
"coverage": {
"state": "usable",
"events_indexed": 1184,
"horizon_months": 38,
"as_of": "2026-08-19T06:12:04Z"
},
"interests": [
{ "topic": "japanese_cuisine", "score": 0.91, "evidence_events": 63, "trend": "rising" },
{ "topic": "natural_wine", "score": 0.74, "evidence_events": 21, "trend": "stable" },
{ "topic": "street_food", "score": 0.58, "evidence_events": 17, "trend": "rising" }
],
"traits": {
"novelty_seeking": 0.82,
"social_orientation": 0.67,
"spontaneity": 0.69
},
"rhythms": {
"dining_out_per_week": 2.4,
"peak_days": ["fri", "sat"]
}
}
| Parameter | Description |
|---|---|
| scope | Required. One of dining travel style fitness social entertainment general. Scopes are enabled per key at onboarding. |
| min_state | Optional. Fail with 409 profile_warming instead of returning a partial profile below this coverage state. Default warming. |
| topics_limit | Optional. Max interests returned, ranked by score. Default 20. |
Every field is derived from photo evidence, and every field tells you how many events back it and how far back they go. None of it is self-reported, and none of it comes from browsing history or data brokers.
| Field | Type | Meaning |
|---|---|---|
| interests[] | array | Topics from Gold's taxonomy. Each carries score 0–1, evidence_events, trend (rising / stable / fading), and first_seen / last_seen months. |
| traits Beta | object | Beta while we calibrate across partner cohorts; expect scores to move between releases. Behavioral tendencies scored 0–1: novelty_seeking, social_orientation, spontaneity, outdoor_orientation, aesthetic_attention. Computed over the full horizon, not single events. |
| rhythms | object | Frequency patterns per scope: weekly rates, peak days, seasonality. Forty gym events over two years is a much stronger signal than one gym photo, so counts are preserved. |
| coverage | object | How much history backs this response: state, events_indexed, horizon_months, as_of. Present on every response. |
The schema has no identity fields. Names, faces, exact locations, and recognized text never appear in it. See the privacy model.
Indexing is progressive: Gold produces a usable profile from a diverse sample of the roll first, then backfills the full history in the background. Coverage tells you which phase a user is in, so you can decide when personalization is trustworthy enough to show.
The first minutes after consent. The profile is partial, so treat it as a hint rather than something to build on.
A diverse sample of the roll has been indexed and the profile is safe to personalize on. How long this takes depends on library size and device conditions, so gate on the state, not the clock.
The full history has been indexed. Trends and rhythms now reflect the whole time horizon.
In steady state, new photos update only new or changed events; the profile refreshes in the background. as_of on every response reports the last refresh.
| Status | Code | Meaning |
|---|---|---|
| 401 | invalid_key | Missing or revoked secret key. |
| 403 | scope_not_enabled | The requested scope isn't enabled for this key. Scopes are agreed at onboarding. |
| 404 | unknown_user | No profile for this user ID — consent not granted, or the user revoked and the profile was deleted. |
| 409 | profile_warming | Coverage is below your min_state. Includes Retry-After. |
| 429 | rate_limited | Over your key's request budget. Includes Retry-After. |
The exact claim we make, and the one we want partners to repeat accurately: raw photos never leave the device. The phone analyzes photos locally. What it transmits is a compact set of visual features from selected moments, and those features cannot be turned back into an image. No thumbnails, no re-encoded copies. Features are handled by short-lived workers, kept out of logs, and deleted once the profile update is written.
The consent sheet is written in plain language and shown before the photo permission prompt. If a user revokes, their profile is deleted and the API starts returning 404 unknown_user. Full policy: Privacy on embedgold.com.
Lower battery cost for the initial index and smarter thermal pacing on long backfills. coverage.as_of added to all responses.
Coverage states (warming / usable / backfilled) and min_state. Scoped context endpoints replace the single profile dump.
Screenshots and documents now route through a fully local path. Recognized text never contributes to transmitted features.
First design-partner release: GoldKit for iOS, consent sheet, progressive indexing, context API v1.