Skip to main content

Jobs API

Browse job listings, manage career profiles, and submit applications through the jobs board.
All endpoints that modify data require session authentication. The job board listing endpoint (GET /api/jobs/board) is publicly accessible without authentication.

List job listings

GET /api/jobs/board
Returns active job listings with optional filters. No authentication required.

Query parameters

ParameterTypeRequiredDescription
statusstringNoFilter by listing status. Defaults to active.
roleTypestringNoFilter by role type (for example, frontend, backend, fullstack).
senioritystringNoFilter by seniority level (for example, junior, mid, senior).
webTypestringNoFilter by web type (for example, web2, web3, both). Defaults to both when creating listings.
searchstringNoFull-text search across job titles and descriptions (case-insensitive).

Response

{
  "jobs": [
    {
      "id": "clxyz123",
      "companyId": "clxyz456",
      "title": "Senior Frontend Engineer",
      "description": "Build next-generation interfaces...",
      "salaryMin": 120000,
      "salaryMax": 180000,
      "salaryCurrency": "USD",
      "roleType": "frontend",
      "techStack": ["React", "TypeScript", "Next.js"],
      "seniority": "senior",
      "contractType": "full-time",
      "webType": "both",
      "applyUrl": "https://example.com/apply",
      "language": "en",
      "languagePtBr": null,
      "status": "active",
      "tier": "standard",
      "viewCount": 42,
      "applyCount": 5,
      "badgeResponseGuaranteed": true,
      "badgeNoAiScreening": false,
      "publishedAt": "2026-04-01T00:00:00Z",
      "createdAt": "2026-03-28T12:00:00Z",
      "updatedAt": "2026-04-01T00:00:00Z",
      "company": {
        "id": "clxyz456",
        "advertiserId": "user_123",
        "name": "Acme Corp",
        "slug": "acme-corp",
        "logoUrl": "https://example.com/logo.png",
        "website": "https://example.com",
        "description": "Building the future of work",
        "githubOrg": "acme-corp",
        "hiredCount": 0,
        "createdAt": "2026-03-20T00:00:00Z",
        "updatedAt": "2026-03-28T12:00:00Z"
      }
    }
  ]
}
FieldTypeDescription
jobsarrayList of job listings (max 50), ordered by publish date descending
jobs[].idstringListing identifier
jobs[].companyIdstringCompany identifier
jobs[].titlestringJob title
jobs[].descriptionstringJob description
jobs[].salaryMinnumberMinimum salary
jobs[].salaryMaxnumberMaximum salary
jobs[].salaryCurrencystringSalary currency code (for example, USD)
jobs[].roleTypestringRole type
jobs[].techStackstring[]Required technologies
jobs[].senioritystringSeniority level
jobs[].contractTypestringContract type (for example, full-time, contract)
jobs[].webTypestringWeb type (web2, web3, or both)
jobs[].applyUrlstringExternal application URL
jobs[].languagestringPrimary language for the listing
jobs[].languagePtBrstring | nullPortuguese (Brazil) translation of the listing
jobs[].statusstringListing status
jobs[].tierstringListing tier (for example, standard)
jobs[].viewCountnumberNumber of views
jobs[].applyCountnumberNumber of applications
jobs[].badgeResponseGuaranteedbooleanWhether the company guarantees a response
jobs[].badgeNoAiScreeningbooleanWhether the company opts out of AI screening
jobs[].publishedAtstring | nullISO 8601 publish timestamp
jobs[].createdAtstringISO 8601 creation timestamp
jobs[].updatedAtstringISO 8601 last update timestamp
jobs[].companyobjectCompany details (included via relation)
jobs[].company.idstringCompany identifier
jobs[].company.advertiserIdstring | nullOwner user identifier
jobs[].company.namestringCompany name
jobs[].company.slugstringURL-friendly company identifier
jobs[].company.logoUrlstring | nullCompany logo URL
jobs[].company.websitestringCompany website
jobs[].company.descriptionstring | nullCompany description
jobs[].company.githubOrgstring | nullGitHub organization name
jobs[].company.hiredCountnumberNumber of hires through the platform
jobs[].company.createdAtstringISO 8601 creation timestamp
jobs[].company.updatedAtstringISO 8601 last update timestamp

Create a job listing

POST /api/jobs/board
Creates a new job listing under a company you own. Requires session authentication.

Request body

FieldTypeRequiredDescription
companyIdstringYesCompany identifier. Must be owned by the authenticated user.
titlestringYesJob title (minimum 1 character).
descriptionstringYesJob description (minimum 1 character).
salaryMinnumberYesMinimum salary (must be positive).
salaryMaxnumberYesMaximum salary (must be positive).
salaryCurrencystringNoSalary currency code. Defaults to USD.
roleTypestringYesRole type (for example, frontend, backend, fullstack).
techStackstring[]NoRequired technologies. Defaults to an empty array.
senioritystringYesSeniority level (for example, junior, mid, senior).
contractTypestringYesContract type (for example, full-time, contract, freelance).
webTypestringNoWeb type. Defaults to both.
applyUrlstringYesExternal application URL. Must be a valid URL.
languagestringNoPrimary listing language. Defaults to en.
languagePtBrstringNoPortuguese (Brazil) translation of the listing.
badgeResponseGuaranteedbooleanNoGuarantee a response to applicants. Defaults to false.
badgeNoAiScreeningbooleanNoOpt out of AI screening. Defaults to false.
New listings are created with a draft status. Publish the listing by updating its status separately.

Response (200)

{
  "job": {
    "id": "clxyz789",
    "companyId": "clxyz456",
    "title": "Senior Frontend Engineer",
    "description": "Build next-generation interfaces...",
    "salaryMin": 120000,
    "salaryMax": 180000,
    "salaryCurrency": "USD",
    "roleType": "frontend",
    "techStack": ["React", "TypeScript"],
    "seniority": "senior",
    "contractType": "full-time",
    "webType": "both",
    "applyUrl": "https://example.com/apply",
    "language": "en",
    "status": "draft",
    "badgeResponseGuaranteed": false,
    "badgeNoAiScreening": false,
    "company": {
      "id": "clxyz456",
      "name": "Acme Corp",
      "slug": "acme-corp"
    }
  }
}

Errors

CodeDescription
400Validation error. The response body contains the Zod validation issues.
401Unauthorized
403Company not found or not owned by the authenticated user
500Internal server error

Create a company

POST /api/jobs/board
Creates a new company profile for posting job listings. Send type: "company" in the request body to create a company instead of a listing. Requires session authentication.

Request body

FieldTypeRequiredDescription
typestringYesMust be "company".
namestringYesCompany name (minimum 1 character).
slugstringYesURL-friendly identifier. Must contain only lowercase letters, numbers, and hyphens.
logoUrlstringNoURL to the company logo.
websitestringYesCompany website. Must be a valid URL.
descriptionstringNoCompany description.
githubOrgstringNoGitHub organization name.

Response (200)

{
  "company": {
    "id": "clxyz456",
    "advertiserId": "user_123",
    "name": "Acme Corp",
    "slug": "acme-corp",
    "logoUrl": "https://example.com/logo.png",
    "website": "https://example.com",
    "description": "Building the future of work",
    "githubOrg": "acme-corp",
    "hiredCount": 0,
    "createdAt": "2026-04-01T00:00:00Z",
    "updatedAt": "2026-04-01T00:00:00Z"
  }
}

Errors

CodeDescription
400Validation error. The response body contains the Zod validation issues.
401Unauthorized
500Internal server error

Apply to a job

POST /api/jobs/apply
Submits an application to an active job listing. Requires session authentication. You can only apply to each listing once.

Request body

FieldTypeRequiredDescription
listingIdstringYesJob listing identifier to apply to.

Response (200)

{
  "application": {
    "id": "clxyz101",
    "listingId": "clxyz789",
    "userId": "user_123",
    "hasProfile": true,
    "createdAt": "2026-04-07T04:00:00Z"
  }
}
FieldTypeDescription
application.idstringApplication identifier
application.listingIdstringJob listing identifier
application.userIdstringApplicant user identifier
application.hasProfilebooleanWhether the applicant has a career profile at the time of application
application.createdAtstringISO 8601 application timestamp

Errors

CodeDescription
400Already applied to this listing
401Unauthorized
404Job not found or not active
500Internal server error

List your applications

GET /api/jobs/apply
Returns all job applications submitted by the authenticated user, ordered by most recent first. Includes listing and company details. Requires session authentication.

Response

{
  "applications": [
    {
      "id": "clxyz101",
      "listingId": "clxyz789",
      "userId": "user_123",
      "hasProfile": true,
      "createdAt": "2026-04-07T04:00:00Z",
      "listing": {
        "id": "clxyz789",
        "title": "Senior Frontend Engineer",
        "status": "active",
        "company": {
          "id": "clxyz456",
          "name": "Acme Corp",
          "slug": "acme-corp"
        }
      }
    }
  ]
}

Errors

CodeDescription
401Unauthorized

Get career profile

GET /api/jobs/career
Returns the authenticated user’s career profile. Requires session authentication.

Response

{
  "profile": {
    "id": "clxyz202",
    "userId": "user_123",
    "skills": ["React", "TypeScript", "Node.js"],
    "seniority": "senior",
    "yearsExperience": 8,
    "bio": "Full-stack engineer with a passion for developer tools.",
    "webType": "both",
    "contractTypes": ["full-time", "contract"],
    "salaryMin": 120000,
    "salaryMax": 180000,
    "salaryCurrency": "USD",
    "salaryVisible": false,
    "languages": ["en", "pt-BR"],
    "timezone": "America/New_York",
    "linkPortfolio": "https://portfolio.example.com",
    "linkLinkedin": "https://linkedin.com/in/example",
    "linkWebsite": "https://example.com",
    "openToWork": true
  }
}
FieldTypeDescription
profileobject | nullCareer profile, or null if no profile exists yet
profile.skillsstring[]Listed skills
profile.senioritystringSeniority level
profile.yearsExperiencenumber | nullYears of experience
profile.biostringShort bio
profile.webTypestringPreferred web type (web2, web3, or both)
profile.contractTypesstring[]Preferred contract types
profile.salaryMinnumber | nullMinimum salary expectation
profile.salaryMaxnumber | nullMaximum salary expectation
profile.salaryCurrencystringSalary currency code
profile.salaryVisiblebooleanWhether salary expectations are visible to employers
profile.languagesstring[]Spoken languages
profile.timezonestring | nullPreferred timezone
profile.linkPortfoliostring | nullPortfolio URL
profile.linkLinkedinstring | nullLinkedIn profile URL
profile.linkWebsitestring | nullPersonal website URL
profile.openToWorkbooleanWhether you are actively looking for work

Errors

CodeDescription
401Unauthorized

Create or update career profile

PUT /api/jobs/career
Creates or updates the authenticated user’s career profile. If a profile already exists, it is updated in place. Requires session authentication.

Request body

FieldTypeRequiredDescription
skillsstring[]NoListed skills. Defaults to an empty array.
senioritystringYesSeniority level.
yearsExperiencenumberNoYears of experience.
biostringYesShort bio.
webTypestringNoPreferred web type. Defaults to both.
contractTypesstring[]NoPreferred contract types. Defaults to an empty array.
salaryMinnumberNoMinimum salary expectation.
salaryMaxnumberNoMaximum salary expectation.
salaryCurrencystringNoSalary currency code. Defaults to USD.
salaryVisiblebooleanNoShow salary expectations to employers. Defaults to false.
languagesstring[]NoSpoken languages. Defaults to an empty array.
timezonestringNoPreferred timezone.
linkPortfoliostringNoPortfolio URL.
linkLinkedinstringNoLinkedIn profile URL.
linkWebsitestringNoPersonal website URL.
openToWorkbooleanNoWhether you are actively looking for work. Defaults to false.

Response (200)

{
  "profile": {
    "id": "clxyz202",
    "userId": "user_123",
    "skills": ["React", "TypeScript"],
    "seniority": "senior",
    "bio": "Full-stack engineer.",
    "openToWork": true
  }
}

Errors

CodeDescription
400Validation error. The response body contains the Zod validation issues.
401Unauthorized
500Internal server error

List your companies

GET /api/jobs/companies
Returns all companies owned by the authenticated user, including summary statistics for each listing. Requires session authentication.

Response

{
  "companies": [
    {
      "id": "clxyz456",
      "advertiserId": "user_123",
      "name": "Acme Corp",
      "slug": "acme-corp",
      "logoUrl": "https://example.com/logo.png",
      "website": "https://example.com",
      "description": "Building the future of work",
      "githubOrg": "acme-corp",
      "hiredCount": 0,
      "createdAt": "2026-04-01T00:00:00Z",
      "updatedAt": "2026-04-01T00:00:00Z",
      "jobs": [
        {
          "id": "clxyz789",
          "title": "Senior Frontend Engineer",
          "status": "active",
          "viewCount": 42,
          "applyCount": 5
        }
      ]
    }
  ]
}
FieldTypeDescription
companiesarrayList of companies owned by the authenticated user, ordered by creation date descending
companies[].idstringCompany identifier
companies[].advertiserIdstring | nullOwner user identifier
companies[].namestringCompany name
companies[].slugstringURL-friendly company identifier
companies[].logoUrlstring | nullCompany logo URL
companies[].websitestringCompany website
companies[].descriptionstring | nullCompany description
companies[].githubOrgstring | nullGitHub organization name
companies[].hiredCountnumberNumber of hires through the platform
companies[].createdAtstringISO 8601 creation timestamp
companies[].updatedAtstringISO 8601 last update timestamp
companies[].jobsarraySummary of job listings under this company
companies[].jobs[].idstringListing identifier
companies[].jobs[].titlestringJob title
companies[].jobs[].statusstringListing status
companies[].jobs[].viewCountnumberNumber of views
companies[].jobs[].applyCountnumberNumber of applications

Errors

CodeDescription
401Unauthorized

List external jobs

GET /api/jobs/external
Returns job listings from external partner boards. Currently aggregates listings from Git City. No authentication required. Results are cached for five minutes.

Response

{
  "jobs": [
    {
      "id": "gitcity-42",
      "title": "Backend Engineer",
      "description": "Build scalable APIs and microservices...",
      "salaryMin": 100000,
      "salaryMax": 160000,
      "salaryCurrency": "USD",
      "roleType": "backend",
      "techStack": ["Node.js", "PostgreSQL"],
      "seniority": "senior",
      "contractType": "clt",
      "webType": "web2",
      "applyUrl": "https://www.thegitcity.com/jobs/42",
      "status": "active",
      "viewCount": 120,
      "applyCount": 8,
      "publishedAt": "2026-04-05T12:00:00Z",
      "company": {
        "name": "Acme Corp",
        "slug": "acme-corp",
        "logoUrl": "https://example.com/logo.png",
        "website": "https://example.com"
      },
      "source": "gitcity"
    }
  ]
}
FieldTypeDescription
jobsarrayList of external job listings
jobs[].idstringListing identifier, prefixed with the source name (for example, gitcity-42)
jobs[].titlestringJob title
jobs[].descriptionstringPlain-text job description (HTML stripped, truncated to 500 characters)
jobs[].salaryMinnumber | nullMinimum salary
jobs[].salaryMaxnumber | nullMaximum salary
jobs[].salaryCurrencystring | nullSalary currency code
jobs[].roleTypestring | nullRole type
jobs[].techStackstring[]Required technologies
jobs[].senioritystring | nullSeniority level
jobs[].contractTypestring | nullContract type. A fulltime value from the source is mapped to clt.
jobs[].webTypestring | nullWeb type
jobs[].applyUrlstringExternal application URL
jobs[].statusstring | nullListing status
jobs[].viewCountnumberNumber of views
jobs[].applyCountnumberNumber of applications
jobs[].publishedAtstring | nullISO 8601 publish timestamp
jobs[].companyobjectCompany details from the external source
jobs[].company.namestringCompany name
jobs[].company.slugstringURL-friendly company identifier
jobs[].company.logoUrlstring | nullCompany logo URL
jobs[].company.websitestringCompany website
jobs[].sourcestringSource identifier (for example, gitcity)
External jobs cannot be applied to through the Agentbot API. Use the applyUrl to apply on the source site.

Errors

CodeDescription
500Failed to fetch external jobs. Returns { "jobs": [], "error": "Failed to fetch external jobs" }.

List sponsors

GET /api/jobs/sponsors
Returns companies that have made hires through the platform, ordered by hire count. No authentication required.

Response

{
  "sponsors": [
    {
      "id": "clxyz456",
      "name": "Acme Corp",
      "slug": "acme-corp",
      "logoUrl": "https://example.com/logo.png",
      "website": "https://example.com",
      "description": "Building the future of work",
      "hiredCount": 12
    }
  ]
}
FieldTypeDescription
sponsorsarrayList of sponsor companies (max 20), ordered by hire count descending
sponsors[].idstringCompany identifier
sponsors[].namestringCompany name
sponsors[].slugstringURL-friendly company identifier
sponsors[].logoUrlstring | nullCompany logo URL
sponsors[].websitestringCompany website
sponsors[].descriptionstring | nullCompany description
sponsors[].hiredCountnumberNumber of hires through the platform
If the sponsors list cannot be loaded, the endpoint returns an empty array instead of an error.

Register as a sponsor

POST /api/jobs/sponsors
Creates a new company profile as a sponsor. Requires session authentication.

Request body

FieldTypeRequiredDescription
namestringYesCompany name.
websitestringYesCompany website URL.
descriptionstringNoCompany description.
tierstringNoSponsorship tier. Accepted by the endpoint but not stored on the company record.
budgetnumberNoSponsorship budget. Accepted by the endpoint but not stored on the company record.
contactEmailstringNoContact email. Accepted by the endpoint but not stored on the company record.
The slug is automatically generated from the company name. The tier, budget, and contactEmail fields are accepted in the request but are not persisted on the company record.

Response (200)

{
  "sponsor": {
    "id": "clxyz456",
    "advertiserId": "user_123",
    "name": "Acme Corp",
    "slug": "acme-corp",
    "website": "https://example.com",
    "description": "Building the future of work",
    "hiredCount": 0
  }
}

Errors

CodeDescription
401Unauthorized
500Failed to create sponsor

Get job status

GET /api/jobs/:jobId
Returns the status of a background job by its identifier. Requires session authentication. You can only access jobs that belong to your account. See Platform jobs for details on the background job queue.

Path parameters

ParameterTypeDescription
jobIdstringJob identifier

Response

{
  "job": {
    "id": "job_abc123",
    "userId": "user_123",
    "status": "completed",
    "error": null,
    "result": {}
  }
}
FieldTypeDescription
job.idstringJob identifier (prefixed with job_)
job.userIdstring | nullUser who owns this job
job.statusstringJob status (queued, running, completed, or failed)
job.errorstring | nullError message if the job failed
job.resultobject | nullJob result data when completed

Errors

CodeDescription
401Unauthorized
403Forbidden — the job belongs to a different user
404Job not found