Y2 Elite workspaces are rolling out for teams
Y2Y2Docs

Manage Profiles through the API

List subscriptions, create and update owned profiles, configure delivery, and retrieve reports

Profiles define recurring intelligence research: topic, schedule, status, instructions, and report configuration. Subscriptions connect a profile to a delivery method. The API represents them as separate resources.

List rows contain two resources

GET /api/v1/profiles lists active subscriptions in the API key's user or workspace context. Every row contains subscription and profile; it is not a flat catalog of every public profile.

Required scopes

OperationScope
List subscribed profilesprofiles:read
Create, replace, patch, or delete an owned profileprofiles:write
Change subscription delivery or manage webhook configurationswebhooks:manage

Profile creation and configuration features still follow the active workspace's plan limits. API write access does not bypass profile, audio, branding, workspace, or delivery entitlements.

List subscriptions and profiles

curl "https://api.y2.dev/api/v1/profiles" \
  --header "Authorization: Bearer $Y2_API_KEY"

Each row has this shape:

{
  "subscription": {
    "id": "sub_0123456789abcdef01234567",
    "profileId": "prf_0123456789abcdef01234567",
    "active": true,
    "delivery": {
      "method": "email",
      "emailAudience": "individual",
      "webhookId": null
    }
  },
  "profile": {
    "id": "prf_0123456789abcdef01234567",
    "name": "Critical Supplier Risk",
    "status": "active",
    "frequency": "daily"
  }
}

profile can be null if the subscribed resource no longer resolves. Save both IDs: prf_... identifies research configuration, while sub_... identifies delivery preferences.

The list is not cursor-paginated today: links.next and meta.page.nextCursor are always null.

Create an owned profile

Creation requires name, topic, frequency, and scheduleTimeOfDay. Times are UTC. The server creates the profile as active, schedules it, and creates an active subscription for the same tenant context.

curl "https://api.y2.dev/api/v1/profiles" \
  --request POST \
  --header "Authorization: Bearer $Y2_API_KEY" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: supplier-risk-2026-07-21" \
  --data '{
    "name": "Critical Supplier Risk",
    "topic": "Monitor disruption affecting semiconductor suppliers, ports, export controls, severe weather, labor actions, and cyber incidents.",
    "frequency": "daily",
    "scheduleTimeOfDay": "08:00",
    "tags": ["supply-chain", "semiconductors"]
  }'

Supported frequencies are daily, weekly, biweekly, and monthly. Weekly and biweekly profiles can supply scheduleDayOfWeek; monthly profiles can supply scheduleDayOfMonth. See Scheduling for the product semantics, including the twice-monthly biweekly schedule.

A successful create returns 201 with:

  • the canonical prf_... resource in data
  • Location containing its canonical API path
  • ETag for that representation
  • the supplied Idempotency-Key, when present

Idempotency keys must contain 8–200 letters, numbers, ., _, :, or -. They are tenant- and operation-scoped for 24 hours. Reusing a key with a different canonical body returns 409 IDEMPOTENCY_CONFLICT.

Patch one or more fields

Use PATCH when omitted fields must remain unchanged.

curl "https://api.y2.dev/api/v1/profiles/$PROFILE_ID" \
  --request PATCH \
  --header "Authorization: Bearer $Y2_API_KEY" \
  --header "Content-Type: application/json" \
  --header "If-Match: $PROFILE_ETAG" \
  --data '{
    "status": "paused",
    "tags": ["supply-chain", "semiconductors", "paused-review"]
  }'

Mutable fields include the profile's name, topic, status, schedule inputs, community visibility, tags, custom instructions, report structure, search/model/budget/recursion/freshness/audio/tool configuration, and branding template. The generated reference defines each nested input.

Profile updates do not change subscription delivery

PUT and PATCH /profiles/{profileId} change profile configuration only. Use the subscription delivery endpoint with the sub_... ID to select email, SMS, or a webhook.

Replace mutable state

Use PUT only when sending the full intended mutable profile state. It requires the same four fields as creation. Optional mutable fields omitted from a replacement reset to their defaults or are cleared.

curl "https://api.y2.dev/api/v1/profiles/$PROFILE_ID" \
  --request PUT \
  --header "Authorization: Bearer $Y2_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Critical Supplier Risk",
    "topic": "Monitor current disruption across strategic semiconductor supply chains.",
    "frequency": "weekly",
    "scheduleTimeOfDay": "08:00",
    "scheduleDayOfWeek": "monday",
    "tags": ["supply-chain"]
  }'

Use the ETag returned by create or a previous update as If-Match when preventing a lost update. If-Match is optional; a stale value returns 412 PRECONDITION_FAILED and the current ETag. There is currently no GET /profiles/{profileId} operation that returns an ETag.

Change delivery on the subscription

Read subscription.id from GET /profiles, then call:

curl "https://api.y2.dev/api/v1/subscriptions/$SUBSCRIPTION_ID/delivery" \
  --request PATCH \
  --header "Authorization: Bearer $Y2_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "deliveryMethod": "webhook",
    "webhookConfigId": "whk_0123456789abcdef01234567"
  }'

Delivery methods are email, sms, webhook, and both_email_sms. A webhook delivery requires an active, authorized whk_... configuration. For email-capable delivery, emailAudience can be individual or, on a plan with member seats, workspace.

Retrieve reports for a profile

The profile's links.reports value is the canonical filtered collection. You can also compose it directly:

curl --get "https://api.y2.dev/api/v1/reports" \
  --header "Authorization: Bearer $Y2_API_KEY" \
  --data-urlencode "profileId=$PROFILE_ID" \
  --data-urlencode "limit=1"

This requires reports:read in addition to whichever profile scopes the client uses.

Delete an owned profile

curl "https://api.y2.dev/api/v1/profiles/$PROFILE_ID" \
  --request DELETE \
  --header "Authorization: Bearer $Y2_API_KEY" \
  --header "If-Match: $PROFILE_ETAG"

Deletion is permanent. It cancels the scheduled job and deletes the profile's subscriptions, signals, reports, and stored audio before returning 204 with no body. The API returns 404 when the key cannot access or mutate the named profile, which avoids revealing another tenant's resource.

In a shared workspace, write-role membership is required. Non-admin members can update or delete only profiles they created; workspace administrators can manage tenant-scoped profiles.