Indeed Job Search icon

Indeed Job Search data API

Indeed Jobs · Identity

Indeed Job Search exposes a graph-style job API — illustrated below as /v1/jobs/recommendations and /v1/jobs/cards — plus REST-style calls for application status (/v1/applications/status), interviews (/v1/interviews/list), unread counts, session-to-token exchange (/v1/auth/token) and keyword typeahead (/v1/suggest/keywords).

Indeed Job Search (package com.indeed.android.jobsearch, version 296.1.0) is Indeed's Android client for job search, applications, interviews and employer messaging. Behind the home feed, My Jobs, sign-in and inbox screens the app calls a graph-style job API (recommended jobs, job-card hydration, session init, account profile, employer conversations, recent searches, resume tags) plus REST-style endpoints for application status, interview lists, unread message counts, session-to-token exchange, keyword autocomplete and new-job counts. Anonymous calls send an app API-key header with country and locale headers; signed-in calls add an OAuth Bearer access token.

Screenshots

  • Indeed Job Search screenshot 1
  • Indeed Job Search screenshot 2
  • Indeed Job Search screenshot 3
  • Indeed Job Search screenshot 4
  • Indeed Job Search screenshot 5
  • Indeed Job Search screenshot 6
  • Indeed Job Search screenshot 7
  • Indeed Job Search screenshot 8

API surface

  • Find relevant jobs (widget)

    POST /v1/jobs/recommendations opendata

    Powers the Android home-screen widget: up to five relevant jobs with matchReason, title, sourceEmployerName, overallRating, compensation.formattedText and viewJobRedirectClickUrl.

    Auth: App API-key header plus country, locale, client and tracking headers. Optional OAuth Bearer access token after sign-in.

    • findRelevantJobs
    • trackingKey
    • matchReason
    • title
    • sourceEmployerName
    • employer
    • key
    • overallRating
    • location
    • formatted
    • compensation
    • formattedText
    • indeedApply
    • scopes
    • dateOnIndeed
    • description
    • viewJobRedirectClickUrl

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/jobs/recommendations HTTP/1.1
    Content-Type: application/json
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    X-Client: android-widget
    X-Tracking-Key: <tk>
    
    {
      "limit": 5,
      "context": "homeWidget"
    }
    {
      "trackingKey": "1abcdefghijklmn",
      "results": [{
        "matchReason": {"type": "RECENT_QUERY", "query": "product manager", "location": "Austin, TX"},
        "job": {
          "title": "Staff Product Manager",
          "sourceEmployerName": "Example Corp",
          "employer": {"key": "example-corp", "overallRating": {"value": 4.1}},
          "location": {"formatted": {"short": "Austin, TX"}},
          "compensation": {"key": "USD_140K_180K", "formattedText": "$140,000 - $180,000 a year"},
          "indeedApply": {"scopes": ["RESUME"]},
          "dateOnIndeed": "2026-09-24T12:00:00Z",
          "description": {"text": "Own the job-seeker home feed."}
        },
        "viewJobRedirectClickUrl": "https://example.com/viewjob?jk=abc123"
      }]
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the home-screen widget's job-refresh flow.
    • Observed in the widget payload that carries up to five recommended jobs with match reasons.
  • Hydrate job cards

    POST /v1/jobs/cards opendata

    Hydrates SERP and conversation job cards from jobKeys: title, formatted location, employer logos, overallRating, compensation.formattedText and attributes.

    Auth: App API-key header plus country, locale and tracking headers. Optional OAuth Bearer access token.

    • jobData
    • key
    • url
    • title
    • location
    • formatted
    • short
    • long
    • sourceEmployerName
    • squareLogoUrls
    • url64
    • url128
    • overallRating
    • compensation
    • formattedText
    • attributes
    • label

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/jobs/cards HTTP/1.1
    Content-Type: application/json
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    X-Tracking-Key: <tk>
    
    {
      "jobKeys": ["abc123def456"]
    }
    {
      "results": [{
        "job": {
          "key": "abc123def456",
          "url": "https://example.com/viewjob?jk=abc123def456",
          "title": "Staff Product Manager",
          "location": {"formatted": {"short": "Austin, TX", "long": "Austin, TX 78701"}},
          "sourceEmployerName": "Example Corp",
          "employer": {
            "squareLogoUrls": {"url64": "https://example.com/s/logo64.png", "url128": "https://example.com/s/logo128.png"},
            "overallRating": {"value": 4.1}
          },
          "compensation": {"formattedText": "$140,000 - $180,000 a year"},
          "attributes": [{"key": "jobtype", "label": "Full-time"}]
        }
      }]
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the search-results and conversation job-card hydration flow.
  • Jobseeker mobile app init

    POST /v1/session/init opendata

    Bootstraps the jobseeker session: cookie tracking key (ctk), service URLs, experiment buckets, IP country, terms-of-service banner and force-upgrade flags.

    Auth: App API-key header plus country and locale headers. Optional OAuth Bearer access token.

    • jobseekerMobileAppInit
    • ctk
    • services
    • name
    • url
    • proctorResult
    • deviceId
    • matrixVersion
    • ipCountry
    • ipLookupCountry
    • attributionParametersPayload
    • affiliateKey
    • showBlockingTOSBanner
    • showForceUpgradeModal
    • tosModalContent

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/session/init HTTP/1.1
    Content-Type: application/json
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    
    {
      "platform": "ANDROID",
      "appVersion": "296.1.0"
    }
    {
      "ctk": "1ctkexample",
      "services": [{"name": "jobgraph", "url": "https://example.com/v1"}],
      "proctorResult": {"deviceId": "dev-9f2a", "matrixVersion": "2026.09.1"},
      "ipCountry": "US",
      "ipLookupCountry": "US",
      "attributionParametersPayload": {"affiliateKey": "", "host": "www.example.com", "keywords": "product manager"},
      "showBlockingTOSBanner": false,
      "showForceUpgradeModal": false,
      "tosModalContent": {"version": "2026-01"}
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the app launch sequence that bootstraps the jobseeker session.
  • Current Passport account

    POST /v1/account/profile osint

    Loads the signed-in Passport identity used by the Me tab — firstName, lastName, emailAddress, isVerified, accountId — plus inbox unread counters.

    Auth: OAuth Bearer access token from the session-token exchange, plus app API-key, country and locale headers.

    • currentUser
    • PassportAccount
    • firstName
    • lastName
    • emailAddress
    • isVerified
    • accountId
    • isConfirmed
    • isSignedIn
    • creationDate
    • globalUnreadEventCount
    • unreadConversationCount

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/account/profile HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer <access_token>
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    
    {
      "include": ["accountProfile", "unreadCounts"]
    }
    {
      "currentUser": {
        "account": {
          "type": "PassportAccount",
          "accountProfile": {
            "accountName": {"firstName": "Alex", "lastName": "Rivera"},
            "email": {"emailAddress": "[email protected]", "isVerified": true}
          },
          "accountId": "acct-1001",
          "emailAddress": "[email protected]",
          "isConfirmed": true,
          "isSignedIn": true,
          "creationDate": "2019-04-12T08:11:00Z"
        }
      },
      "globalUnreadEventCount": 3,
      "unreadConversationCount": 2
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the Me tab's signed-in account loading flow.
  • Find employer conversations

    POST /v1/messages/conversations osint

    Pages the signed-in jobseeker inbox: conversation id, unreadCount, employer participants, attached job, lastEvent.messagePreview and moderationStatus.

    Auth: OAuth Bearer access token from the session-token exchange, plus app API-key, country, locale and tracking headers.

    • findConversations
    • conversations
    • id
    • unreadCount
    • participants
    • role
    • accountKey
    • participantName
    • job
    • key
    • title
    • lastEvent
    • messagePreview
    • locks
    • reasonCode
    • moderationStatus
    • pageInfo

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/messages/conversations HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer <access_token>
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    X-Tracking-Key: <tk>
    
    {
      "conversationFilter": {"excludedLabels": ["ARCHIVE", "SPAM"]},
      "first": 20
    }
    {
      "conversations": [{
        "id": "Y29udjoxMjM",
        "userReadsInfo": {"unreadCount": 1},
        "participants": [{"role": "EMPLOYER", "accountKey": "emp-441", "participantName": "Example Corp Recruiter"}],
        "job": {"key": "abc123def456", "title": "Staff Product Manager"},
        "lastEvent": {"type": "MESSAGE", "messagePreview": "Are you free Thursday?"},
        "locks": {"reasonCode": null},
        "moderationStatus": "NONE"
      }],
      "pageInfo": {"endCursor": "cursor-20", "hasNextPage": true}
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the employer-message inbox paging flow.
  • Recent job searches

    POST /v1/search/recent opendata

    Returns the signed-in jobseeker's recent search criteria (query, location) used to seed the home feed and widget.

    Auth: OAuth Bearer access token from the session-token exchange, plus app API-key, country and locale headers.

    • currentJobSeekerPortrait
    • rawActivities
    • recentJobSearches
    • uid
    • timestamp
    • criteria
    • query
    • location

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/search/recent HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer <access_token>
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    
    {}
    {
      "recentJobSearches": [{
        "uid": "rjs-7788",
        "timestamp": "2026-09-26T18:04:00Z",
        "criteria": {"query": "product manager", "location": "Austin, TX"}
      }]
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the home feed's recent-search seeding behavior.
  • Resume tags on jobseeker profile

    POST /v1/profile/resume-tags osint

    Reads resume id and tags from the signed-in jobSeekerProfile used when applying and matching jobs.

    Auth: OAuth Bearer access token from the session-token exchange, plus app API-key, country and locale headers.

    • jobSeekerProfile
    • profile
    • resume
    • id
    • tags

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/profile/resume-tags HTTP/1.1
    Content-Type: application/json
    Authorization: Bearer <access_token>
    X-App-Key: <app-api-key>
    X-Country: US
    X-Locale: en_US
    
    {}
    {
      "jobSeekerProfile": {
        "profile": {
          "resume": {
            "id": "resume-9",
            "tags": ["product-management", "b2b-saas"]
          }
        }
      }
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the apply flow's resume handling.
  • Application-status jobs (My Jobs)

    GET /v1/applications/status opendata

    Lists applied and visited jobs for the My Jobs tab: jobKey, company.name, pipeline statuses, applyTime, encryptedIaAppId and applicationStatus.

    Auth: Session cookie or OAuth Bearer access token. Query params type, applyUpdateStartTime, tk (tracking key) and from.

    • success
    • appStatusJobs
    • appTk
    • jobTitle
    • jobKey
    • jobUrl
    • jobExpired
    • jobFraudulent
    • withdrawn
    • location
    • company
    • name
    • candidateStatus
    • selfReportedStatus
    • employerJobStatus
    • userJobStatus
    • applyTime
    • indeedApplyable
    • encryptedIaAppId
    • encryptedAdvCandId
    • applicationStatus
    • applicationStatusAction
    • applicationStatusTimestamp

    Illustrative example reconstructed from the app's interface — not a live capture.

    GET /v1/applications/status?type=APPLIED&applyUpdateStartTime=0&tk=<tk>&from=myjobs HTTP/1.1
    Authorization: Bearer <access_token>
    Accept: application/json
    {
      "success": true,
      "body": {
        "appStatusJobs": [{
          "appTk": "1apptk",
          "jobTitle": "Staff Product Manager",
          "jobKey": "abc123def456",
          "jobUrl": "https://example.com/viewjob?jk=abc123def456",
          "jobExpired": false,
          "jobReported": false,
          "jobFraudulent": false,
          "withdrawn": false,
          "location": "Austin, TX",
          "company": {"name": "Example Corp"},
          "statuses": {
            "candidateStatus": {"status": "APPLIED", "timestamp": 1727049600000},
            "selfReportedStatus": {"status": "WAITING", "timestamp": 1727049600000},
            "employerJobStatus": {"status": "ACTIVE", "timestamp": 1727049600000},
            "userJobStatus": {"status": "APPLIED"}
          },
          "applyTime": 1727049600000,
          "indeedApplyable": true,
          "hasIaAppId": true,
          "hasApplicationPreview": true,
          "hasInterviewNowAccess": false,
          "normalizedJobTitle": "product manager",
          "employerEstimatedResponseDays": 7,
          "encryptedIaAppId": "ia-enc-1",
          "encryptedAdvCandId": "cand-enc-1",
          "applicationStatus": "UNDER_REVIEW",
          "applicationStatusAction": "WAIT",
          "applicationStatusTimestamp": 1727136000000,
          "companyApplyUrl": null
        }]
      }
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the My Jobs application-list refresh.
  • List interviews

    GET /v1/interviews/list opendata

    Loads interview invitations for My Jobs: formatType, status, durationInMinutes, invitationNote, jobDetails and timeSlots.

    Auth: Session cookie or OAuth Bearer access token. Query params statuses, formats, start, tk and from.

    • id
    • externalInterviewId
    • formatType
    • status
    • durationInMinutes
    • interviewGTS
    • outcome
    • invitationNote
    • availabilityBasedScheduling
    • jobDetails
    • title
    • company
    • jobKey
    • jobUrl
    • location
    • fraudulent
    • timeSlots

    Illustrative example reconstructed from the app's interface — not a live capture.

    GET /v1/interviews/list?statuses=INVITED,SCHEDULED&formats=VIDEO,PHONE&start=0&tk=<tk>&from=myjobs HTTP/1.1
    Authorization: Bearer <access_token>
    Accept: application/json
    {
      "success": true,
      "body": {
        "interviews": [{
          "id": "int-441",
          "externalInterviewId": "ext-882",
          "formatType": "VIDEO",
          "status": "SCHEDULED",
          "durationInMinutes": "30",
          "interviewGTS": true,
          "outcome": null,
          "invitationNote": "Looking forward to chatting.",
          "availabilityBasedScheduling": true,
          "jobDetails": {
            "title": "Staff Product Manager",
            "company": "Example Corp",
            "jobKey": "abc123def456",
            "jobUrl": "https://example.com/viewjob?jk=abc123def456",
            "location": "Austin, TX",
            "fraudulent": "false",
            "reportedByUser": "false"
          },
          "timeSlots": [{"start": "2026-09-30T16:00:00Z", "end": "2026-09-30T16:30:00Z"}]
        }]
      }
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the interview invitations screen in My Jobs.
  • Unread messages summary

    GET /v1/messages/unread-summary osint

    Badge counts for the Messages tab: totalUnreadConversationCount and totalUnreadMessageCount.

    Auth: Session cookie or OAuth Bearer access token. A fixed client query parameter identifies the Android app.

    • data
    • totalUnreadConversationCount
    • totalUnreadMessageCount

    Illustrative example reconstructed from the app's interface — not a live capture.

    GET /v1/messages/unread-summary?client=android-app HTTP/1.1
    Authorization: Bearer <access_token>
    Accept: application/json
    {
      "data": {
        "totalUnreadConversationCount": 2,
        "totalUnreadMessageCount": 5
      }
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the Messages tab badge update.
  • Convert session cookies to OAuth token

    POST /v1/auth/token osint

    Exchanges sign-in session cookies for an OAuth access_token / expires_in / scope / token_type used as Bearer auth on the app's graph and jobs services.

    Auth: Session cookies on the request (including the refresh-token cookie). Form fields client_id and scope. Subsequent calls send Authorization: Bearer access_token.

    • client_id
    • scope
    • access_token
    • expires_in
    • token_type

    Illustrative example reconstructed from the app's interface — not a live capture.

    POST /v1/auth/token HTTP/1.1
    Content-Type: application/x-www-form-urlencoded
    Cookie: refresh_token=<refresh>
    
    client_id=android-app&scope=openid%20profile%20email
    {
      "access_token": "eyJhbGciOi...",
      "expires_in": 3600,
      "scope": "openid profile email",
      "token_type": "Bearer"
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the sign-in session upgrade flow.
  • Keyword autocomplete (what)

    GET /v1/suggest/keywords opendata

    Typeahead for the What search box: query plus country/language/ctk return suggestion strings used on the search results page.

    Auth: Unauthenticated. Query params query, ctk, country, language, count; optional session identifiers.

    • query
    • ctk
    • country
    • language
    • count
    • formatted
    • suggestion
    • formattedSuggestion

    Illustrative example reconstructed from the app's interface — not a live capture.

    GET /v1/suggest/keywords?query=product%20man&ctk=<ctk>&country=US&language=en&count=8&formatted=1 HTTP/1.1
    Accept: application/json
    [
      {
        "suggestion": "product manager",
        "formattedSuggestion": "<b>product man</b>ager"
      },
      {
        "suggestion": "product management intern",
        "formattedSuggestion": "<b>product man</b>agement intern"
      }
    ]

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the search box typeahead behavior.
  • New jobs count for a saved search

    GET /v1/jobs/new-count opendata

    Returns how many new postings match a saved keyword/location pair since a timestamp — drives the new-jobs badge.

    Auth: Optional sign-in session. Query params hl, q (keyword), l (location) and since (epoch).

    • status
    • body
    • key
    • newCount

    Illustrative example reconstructed from the app's interface — not a live capture.

    GET /v1/jobs/new-count?hl=en&q=product%20manager&l=Austin%2C%20TX&since=1727049600000 HTTP/1.1
    Accept: application/json
    {
      "status": "ok",
      "body": {
        "key": "product manager|Austin, TX",
        "newCount": 14
      }
    }

    Derived from the app's interface; endpoint details are illustrative, not a live capture.

    • Mapped from the saved-search new-jobs badge.

Data categories

  • job listings
  • applications
  • interviews
  • identity
  • messaging
  • search history
  • resumes

Where teams use this data

  • Talent-pipeline reconciliation

    An ATS nightly-syncs My Jobs applicationStatus, encryptedIaAppId and interview formatType/status so recruiters see the same pipeline a candidate sees in Indeed.

  • Job-market pulse from public cards

    A labour-market dashboard hydrates getJobsData cards (title, compensation.formattedText, overallRating, location.formatted) without storing candidate PII.

  • Inbox SLA for employer replies

    A jobseeker CRM watches FindConversations unreadCount plus messaging/jobseekers/v2/summary totals to page when an employer thread goes stale.

  • Identity match at apply time

    A background-check vendor binds Passport firstName/lastName/emailAddress/accountId from initGraph to the resume id returned by GetResumeTags before submitting Indeed Apply.

Frequently asked questions

Where do Indeed job cards come from?

The app posts to a graph-style job API — illustrated as /v1/jobs/recommendations for the home widget and /v1/jobs/cards for result cards — returning title, employer name, compensation text and overall rating.

How does Indeed Job Search authenticate?

Calls send an app API-key header with country and locale headers. After sign-in the app exchanges its session at /v1/auth/token for an OAuth access token sent as Bearer auth.

What identity fields does the signed-in account expose?

The account profile call returns first name, last name, email address, verification state and account id, plus inbox unread counters.

Which calls power My Jobs?

GET /v1/applications/status lists applied jobs with each application's pipeline status; GET /v1/interviews/list lists interview invitations with format, time slots and job details.

Topics

  • Indeed Job Search API
  • Indeed job recommendations API
  • Indeed application status API
  • Indeed session token exchange
  • Indeed interviews API
  • Indeed autocomplete suggestions

Need this app's data API integrated?

We deliver scoped integrations for any named app — from USD 500 with source-code handoff, or hosted access billed per call. Tell us the data you need.

Get a quote