UpHunt API

Webhooks

Receive matched jobs the moment they appear and trigger auto-apply on the fly.

UpHunt can POST to your server whenever a new job matches one of your feeds. Combine webhooks with the Apply API to build a fully automated pipeline.

How it works

Set up a job feed in your Dashboard with a webhook URL.

When a new job matches that feed, UpHunt POSTs the job payload to your URL.

Your server decides whether to apply and (optionally) generates a cover letter.

Call POST /api/auto-apply-v2/apply with the ciphertext from the payload as jobId.

Upwork payload

{
  "title": "React Developer needed",
  "description": "Full job description text...",
  "ciphertext": "~01abc123def456",
  "jobUrl": "https://www.upwork.com/freelance-jobs/apply/~01abc123def456",
 
  "jobType": "HOURLY",
  "budget": {
    "fixedPrice": null,
    "hourlyMin": 30,
    "hourlyMax": 60
  },
  "contractorTier": "Expert",
 
  "jobDetails": { },
  "client": {
    "location": { "city": "New York", "country": "United States" },
    "stats": { "totalAssignments": 42, "score": 4.8 },
    "paymentMethodVerified": true
  },
 
  "skills": [
    { "uid": "1110580482322976768", "name": "React", "highlighted": true },
    { "uid": "996364628012691457", "name": "TypeScript", "highlighted": false }
  ],
 
  "publishTime": "2025-01-20T10:30:00.000Z",
  "matchingScore": 8,
  "jobListenerId": "listener_xyz",
  "jobListenerName": "My Feed",
  "platform": "upwork",
  "timestamp": 1706972400000
}

LinkedIn payload

{
  "jobId": "4368632132",
  "title": "Data Engineer",
  "description": "Full job description text...",
  "company": {
    "name": "Acme Corp",
    "logoUrl": "https://media.licdn.com/...",
    "profileUrl": "https://www.linkedin.com/company/acme-corp",
    "slug": "acme-corp"
  },
  "location": "United Kingdom",
  "seniorityLevel": "Mid-Senior level",
  "employmentType": "Contract",
  "industries": ["Technology", "Healthcare"],
  "salaryRange": "£60.00/hr - £66.00/hr",
  "applicantCount": 25,
  "isEasyApply": true,
  "matchingScore": 8,
  "jobUrl": "https://www.linkedin.com/jobs/view/4368632132",
  "platform": "linkedin",
  "timestamp": 1706972400000
}

Full automation example

Apply automatically to any Upwork job scoring 7+ using a UpHunt-generated cover letter:

app.post('/webhook/uphunt', async (req, res) => {
  const job = req.body
 
  if (job.matchingScore < 7) return res.json({ skipped: true })
 
  const proposalRes = await fetch('https://uphunt.io/api/auto-apply-v2/generate-proposal', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.UPHUNT_API_KEY!,
    },
    body: JSON.stringify({
      jobTitle: job.title,
      jobDescription: job.description,
      reasoningEffort: 'medium',
    }),
  })
  const { proposal: coverLetter } = await proposalRes.json()
 
  const response = await fetch('https://uphunt.io/api/auto-apply-v2/apply', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.UPHUNT_API_KEY!,
    },
    body: JSON.stringify({
      jobId: job.ciphertext,
      coverLetter,
      proposal: { hourlyRate: 65, timeline: '1 to 3 months' },
      autoFillOtherQuestions: true,
    }),
  })
 
  const result = await response.json()
  res.json({ applied: result.success, queueId: result.queueId })
})

Delivery guarantees

Your webhook endpoint must respond with a 2xx status within 10 seconds. For longer processing, return 200 immediately and handle the apply call asynchronously (background queue, worker, etc.).

  • Retries — we retry failed deliveries up to 3 times with exponential backoff (30s, 2m, 10m).
  • Ordering — events are delivered in the order jobs are matched, but concurrent feeds are not strictly ordered.
  • Deduplication — duplicate events for the same (jobId, jobListenerId) are suppressed for 24 hours.

Testing locally

Use a tunnel (ngrok, cloudflared, localtunnel) to expose your local server, then paste the public URL into the feed's webhook field. UpHunt sends a test payload when you save the feed.

On this page