Skip to content

Sourced profiles

Candidates your team found and saved, with contact details already revealed.

A sourced profile is a candidate the workspace went out and found, rather than one who applied. It might come from a Tahoe search, an X-ray search, an import or a GitHub search, and a recruiter saved it. The shape is close to an applicant’s, but the consent footing is different, and every row says so.

GET/sourced-profilessourced_profiles:read

Sourced profiles in the workspace, most recently updated first.

ParameterTypeNotes
originstringWhere the profile came from, such as a Tahoe search, an X-ray search, an import or a GitHub search. For example xray, import or github.
has_contact_infobooleanOnly profiles that do (or do not) have contact details on file. A cheap way to skip rows with nothing to fetch.
qstringMatches part of the name, job title or company, ignoring case.
updated_aftertimestampOnly profiles changed since. Use it for incremental sync.
limitintegerDefault 25, maximum 100.
cursorstringFrom the previous page. Send the same filters with it.
Request
curl "https://tahoe.workonward.com/api/partner/v1/sourced-profiles?origin=xray&has_contact_info=true" \
  -H "Authorization: Bearer $TAHOE_API_KEY"
Response
{
  "object": "list",
  "data": [
    {
      "object": "sourced_profile",
      "id": "cnd_8Fj3kLm2Qd7s",
      "workspace_id": "wsp_4Kd8sPm2Qx7L",
      "full_name": "Priya Raman",
      "headline": "Field Operations Manager at Northwind Logistics",
      "job_title": "Field Operations Manager",
      "company_name": "Northwind Logistics",
      "company_industry": null,
      "company_website": null,
      "company_linkedin_url": null,
      "department": null,
      "management_level": null,
      "location_full": "Columbus, Ohio, United States",
      "location_country": "United States",
      "linkedin_url": "https://www.linkedin.com/in/priya-raman-9x8y7z",
      "photo_url": null,
      "summary": "Runs field crews and equipment for regional distribution sites ...",
      "total_experience_months": null,
      "connections_count": null,
      "follower_count": null,
      "match_score": 81,
      "match_tier": "strong",
      "created_at": "2026-08-19T07:41:02.115Z",
      "updated_at": "2026-09-06T12:08:55.400Z",
      "has_contact_info": true,
      "has_resume": false,
      "has_business_card": false,
      "has_profile_photo": true,
      "has_linkedin_capture": false,
      "provenance": {
        "origin": "sourced",
        "acquisition": "xray_search",
        "provider": "xray",
        "owner_workspace_id": "wsp_4Kd8sPm2Qx7L",
        "first_seen_at": "2026-08-19T07:41:02.115Z",
        "last_seen_at": "2026-09-06T12:08:55.400Z",
        "consent": {
          "basis": "legitimate_interest_sourcing",
          "candidate_facing_notice": false,
          "unsubscribed": false,
          "suppressed": false
        },
        "licence": {
          "redistributable": false,
          "note": "Collected from public professional sources. Not licensed for onward redistribution."
        }
      },
      "links": {
        "self": "/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s",
        "contact_info": "/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s/contact-info",
        "attachments": "/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s/attachments",
        "list_memberships": "/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s/list-memberships"
      }
    }
  ],
  "has_more": true,
  "next_cursor": "cur_eyJrIjoiMjAyNi0wOS0wNlQxMjowODo1NVoi..."
}

How full a profile is depends on where it came from, so expect null in any field. In provenance, acquisition and provider say how the profile was found. The rest of the block is described under The provenance block.

match_score and match_tier are Tahoe’s assessment against the search that found this person, not a general rating. They mean nothing outside that search, so do not show them as a standalone score.

GET/sourced-profiles/{profile_handle}sourced_profiles:read

One profile, in the same shape as a list row.

GET/sourced-profiles/{profile_handle}/contact-infocontact:read

Only the contact details this workspace has already revealed in Tahoe. This endpoint never reveals anything new and never spends the workspace’s credits. Phone numbers also need contact:phone:read; without it, a phone on file is named in restricted.

Request
curl https://tahoe.workonward.com/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s/contact-info \
  -H "Authorization: Bearer $TAHOE_API_KEY"
Response (shortened)
{
  "object": "contact_info",
  "subject": { "object": "sourced_profile", "id": "cnd_8Fj3kLm2Qd7s" },
  "emails": [
    {
      "value": "[email protected]",
      "kind": "work",
      "status": "found",
      "verified_at": "2026-09-06T12:08:55.400Z",
      "source": {
        "object": "sourced_profile",
        "id": "cnd_8Fj3kLm2Qd7s",
        "workspace_id": "wsp_4Kd8sPm2Qx7L"
      },
      "licence": { "redistributable": false }
    }
  ],
  "phones": [],
  "unsubscribed": false,
  "field_states": {
    "work_email": "found",
    "personal_email": "not_found",
    "phone": "not_found"
  }
}

field_states gives the state of the work email, personal email and phone. A field the workspace never revealed, or revealed without finding anything, shows up there as not_found and not as a value. Here phones is empty and nothing is in restricted, so Tahoe holds no phone number for this person. Had a phone been on file and your key lacked the phone scope, phones would be named in restricted instead.

Each value returned counts one against the daily personal-data budget and is recorded in the audit log with your key, the record and the field. Fetch contact details when someone is about to use them, not for every profile during a sync.

GET/sourced-profiles/{profile_handle}/attachmentsattachments:read

The files held for this profile: a resume, a business_card and a profile_photo, whichever exist. Each file has its own scope, given in required_scope. Files your key cannot read are still listed, with readable: false, so you know they exist.

FileScope needed to download
profile_photoattachments:read
resumeresume:download
business_cardcontact:read (a business card is a picture of contact details)
Response
{
  "object": "list",
  "data": [
    {
      "object": "attachment",
      "type": "resume",
      "filename": "priya-raman.pdf",
      "mime": "application/pdf",
      "bytes": 210444,
      "uploaded_at": "2026-08-21T10:02:19.301000",
      "required_scope": "resume:download",
      "readable": false
    },
    {
      "object": "attachment",
      "type": "profile_photo",
      "filename": "priya-raman.jpg",
      "mime": "image/jpeg",
      "bytes": 48120,
      "uploaded_at": "2026-08-19T07:41:04.882000",
      "required_scope": "attachments:read",
      "readable": true,
      "links": {
        "content": "/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s/attachments/profile_photo/content"
      }
    }
  ],
  "has_more": false,
  "next_cursor": null
}

links.content appears only when readable is true, so a client that follows links never makes a request it is not allowed to make. Unlike other timestamps, uploaded_at on an attachment has no time zone suffix: read it as UTC.

GET/sourced-profiles/{profile_handle}/attachments/{kind}/contentattachments:read

Downloads one file, where kind is profile_photo, resume or business_card. The response is the file itself, not JSON. The key also needs the file’s own scope from the table above. Each download is in the download rate-limit tier (30 per minute), counts one against the daily personal-data budget and is recorded in the audit log.

Request
curl https://tahoe.workonward.com/api/partner/v1/sourced-profiles/cnd_8Fj3kLm2Qd7s/attachments/profile_photo/content \
  -H "Authorization: Bearer $TAHOE_API_KEY" \
  -o priya-raman.jpg

GET/sourced-profiles/{profile_handle}/list-membershipslists:read

Which of the workspace’s candidate lists this profile is in, and its stage in each. This is the sourcing side’s version of an application’s pipeline stage. See Projects and lists.

Response
{
  "object": "list",
  "data": [
    {
      "object": "list_membership",
      "id": "mem_9Xj4kQd7Rm2s",
      "list_id": "lst_3Rp8vKd2mXq4",
      "sourced_profile_id": "cnd_8Fj3kLm2Qd7s",
      "stage": "contacted",
      "stage_updated_at": "2026-09-04T08:12:44.201Z",
      "added_at": "2026-08-19T07:41:02.115Z"
    }
  ],
  "has_more": false,
  "next_cursor": null
}

sourced_profile.created, sourced_profile.updated and sourced_profile.deleted need sourced_profiles:read. sourced_profile.contact_info_revealed needs contact:read, and sourced_profile.attachment_added needs attachments:read. See the change feed.

The reveal event never carries the value, only the fact that new contact details exist. It still needs the contact scope, because knowing that a phone number was just revealed for a named person is valuable on its own.