UpHunt API
API Endpoints

Get Client Jobs

Buyer profile, currently open jobs, and full work history.

GET
/api/clients/:companyId/jobs

Returns the buyer's open jobs and complete work history, alongside aggregate stats — derived from the freshest scrape we have for that company.

The legacy /api/v1/clients/:companyId/jobs and /api/v2/clients/:companyId/jobs paths still work — they forward to this endpoint and behave identically (same x-api-key auth).

Authentication

This endpoint uses the same x-api-key header as the auto-apply endpoints — the key scoped to your UpHunt account. Generate it from Dashboard → Auto-Apply → API & Webhooks.

x-api-key: <your-key>

Path parameters

ParameterTypeDescription
companyIdstringrequired

Upwork company identifier. You can find this on any of the buyer's archived jobs at authJobDetailsResponse.data.jobAuthDetails.buyer.info.company.companyId, or fall back to jobDetailsResponse.data.jobPubDetails.buyer.company.companyId.

Example

cURL
curl "https://uphunt.io/api/clients/1991212616395436888/jobs" -H "x-api-key: YOUR_API_KEY"

Response

{
  "companyId": "1991212616395436888",
  "lastSyncedAt": 1778344861000,
  "buyer": {
    "company":   { "name": "Acme Inc.", "companyId": "1991212616395436888", "isEDCReplicated": null, "contractDate": "2025-11-19T00:00:00.000Z" },
    "location":  { "city": "St..hlingen", "country": "DEU", "countryTimezone": "Europe/Berlin (UTC+02:00)" },
    "stats":     { "totalAssignments": 20, "score": 4.75, "totalCharges": { "amount": 1721.68 }, "feedbackCount": 8, "totalJobsWithHires": 16 },
    "enterprise": false,
    "avgHourlyJobsRate": { "amount": 22.23 },
    "postedCount": 57,
    "topClient": false,
    "phoneVerificationStatus": { "status": "VERIFIED" }
  },
  "openJobs": [
    {
      "id": "2052895097657407455",
      "ciphertext": "~022052895097657407455",
      "title": "LONG-TERM! Only Experienced Video Editor",
      "type": "FIXED",
      "isPtcPrivate": false
    }
  ],
  "workHistory": [
    {
      "isPtcJob": false,
      "status": "ACTIVE",
      "startDate": "2026-03-31T12:23:23.855Z",
      "endDate": null,
      "totalCharge": 235.94,
      "totalHours": 10.33,
      "jobInfo": { "title": "Mighty Networks Architect", "id": "2040846723050472167", "ciphertext": "~022040846723050472167" },
      "contractorInfo": { "contractorName": "Angelia A I.", "ciphertext": "~01cd73bd718fc7f708" },
      "rate": { "amount": 22.22 },
      "feedback": null,
      "feedbackToClient": null
    }
  ],
  "archivedCiphers": ["~022040846723050472167"],
  "archivedJobIds": ["2040846723050472167"]
}

Field notes

ParameterTypeDescription
lastSyncedAtnumber

Unix milliseconds. The openJobs list and buyer stats reflect this moment, not real time.

buyerobject

Buyer-level fields. Some entries (enterprise, phoneVerificationStatus, avgHourlyJobsRate) require auth-enriched scrape data and may be null when only the public payload is available.

openJobsarray

Currently posted jobs from this buyer at lastSyncedAt. Each entry can be opened via Get Job by Ciphertext for the full payload.

workHistoryarray

Past contracts (active and closed). Includes contractor name, dates, total charge, hourly rate, and freelancer/buyer feedback when not suppressed. Private contracts may arrive with jobInfo.ciphertext: null but still expose jobInfo.id.

archivedCiphersstring[]

Subset of ciphertexts mentioned in openJobs + workHistory that we already hold in our archive. Use these to mark rows you can fetch via Get Job by Ciphertext.

archivedJobIdsstring[]

Subset of workHistory[].jobInfo.id values that we already hold. Useful for private past contracts where no ciphertext is exposed.

Errors

StatusWhen
400Missing companyId
401x-api-key missing or invalid
404No archived jobs match the companyId

On this page