My Project
    My Project
    • Careers API

    Careers API

    This document is the single source of truth for all frontend (WordPress / web) integrations.
    Instruction to frontend teams:
    “Build strictly against this contract. Backend behavior is frozen for v2.”
    All endpoints below are versioned, stable, and production-ready.

    🔒 NexaGuard Careers API — Frontend Contract (v2)#

    Base URL#

    https://api.nexaguard.io/v2/careers

    Content-Type#

    Requests: application/json or multipart/form-data
    Responses: application/json

    Authentication#

    Public endpoints: ❌ None required
    Internal endpoints: ✅ Protected (not used by frontend clients)

    1️⃣ GET /jobs — List Open Jobs#

    Purpose#

    Retrieve all open job positions for the Careers landing page.

    Request#

    Optional Query Parameters#

    ParamTypeExampleNotes
    departmentstringCustomer SupportExact match
    job_typestringfull_timeEnum
    remote1|01Remote-only
    qstringsupportSimple search

    ✅ Response — 200 OK#

    {
      "ok": true,
      "jobs": [
        {
          "id": "job_5ffdefc2-1cbe-40de-825d-44a7c588d6f1",
          "slug": "customer-support-specialist",
          "posting_title": "Customer Support Specialist",
          "department": null,
          "job_type": "full_time",
          "is_remote": 1,
          "city": null,
          "province": null,
          "country": "United States",
          "date_opened": null,
          "created_at": "2026-01-11T11:02:36.608Z"
        }
      ]
    }

    Frontend Notes#

    Use slug for routing (/careers/{slug})
    Use posting_title as the job card title
    Use is_remote and location fields for badges

    2️⃣ GET /jobs/{slug} — Job Detail#

    Purpose#

    Retrieve full job details for a single position.

    Request#


    ✅ Response — 200 OK#

    {
      "ok": true,
      "job": {
        "id": "job_5ffdefc2-1cbe-40de-825d-44a7c588d6f1",
        "slug": "customer-support-specialist",
        "posting_title": "Customer Support Specialist",
        "internal_title": null,
        "department": null,
        "industry": null,
        "job_type": "full_time",
        "work_experience": null,
        "number_of_positions": 1,
        "status": "open",
        "is_remote": 1,
        "city": null,
        "province": null,
        "country": "United States",
        "description": "<p>Support NexaGuard customers worldwide.</p>",
        "requirements": "<ul><li>Excellent English</li></ul>",
        "benefits": "<ul><li>Remote</li></ul>",
        "required_skills": ["Customer Support", "Email", "SaaS"],
        "created_at": "2026-01-11T11:02:36.608Z",
        "updated_at": "2026-01-11T11:02:36.608Z"
      }
    }

    Frontend Notes#

    description, requirements, and benefits are HTML
    Render directly (sanitize if your frontend requires)
    required_skills → render as tags/chips

    3️⃣ POST /apply — Submit Application#

    Purpose#

    Submit a job application with resume upload.

    Request#

    Form Fields#

    FieldTypeRequired
    job_slugstring✅
    first_namestring✅
    last_namestring✅
    emailstring✅
    phonestring❌
    resumefile (PDF/DOC/IMG)✅
    sourcestring❌ (default: website)

    ✅ Response — 201 Created#

    {
      "ok": true,
      "application_id": "app_3815c4f5-04f7-49d3-bbb4-32175dd75089",
      "tracking_token": "juSzAOaATDnqNHLyopJctH0AXjEaHJ0bg1CJSICtyQY",
      "status_url": "https://careers.nexaguard.com/careers/application/juSzAOaATDnqNHLyopJctH0AXjEaHJ0bg1CJSICtyQY"
    }

    Error — Already Applied (409)#

    {
      "ok": false,
      "error": "You have already applied for this role.",
      "tracking_token": "..."
    }

    Frontend Notes#

    Persist tracking_token client-side
    Redirect user to status_url
    Do not resubmit application on page refresh

    4️⃣ GET /applications/{tracking_token} — Application Status & Timeline#

    Purpose#

    Allow candidates to track application progress.

    Request#


    ✅ Response — 200 OK#

    {
      "ok": true,
      "application": {
        "id": "app_3815c4f5-04f7-49d3-bbb4-32175dd75089",
        "tracking_token": "juSzAOaATDnqNHLyopJctH0AXjEaHJ0bg1CJSICtyQY",
        "created_at": "2026-01-11T11:10:22.012Z",
        "updated_at": "2026-01-11T11:10:22.012Z",
        "source": "website",
        "current_status": {
          "id": "status_applied",
          "name": "Applied",
          "kind": "normal"
        },
        "current_stage_group": {
          "id": "stage_screening",
          "name": "Screening",
          "position": 1
        },
        "job": {
          "id": "job_5ffdefc2-1cbe-40de-825d-44a7c588d6f1",
          "slug": "customer-support-specialist",
          "posting_title": "Customer Support Specialist",
          "department": null,
          "job_type": "full_time",
          "is_remote": 1,
          "city": null,
          "province": null,
          "country": "United States"
        },
        "candidate": {
          "first_name": "Test",
          "last_name": "Candidate",
          "email": "test.candidate+1@nexaguard.io"
        }
      },
      "pipeline": {
        "stage_groups": [
          { "id": "stage_screening", "name": "Screening", "position": 1, "is_terminal": 0 },
          { "id": "stage_interview", "name": "Interview", "position": 3, "is_terminal": 0 },
          { "id": "stage_hired", "name": "Hired", "position": 5, "is_terminal": 1 }
        ],
        "statuses": [
          {
            "id": "status_applied",
            "name": "Applied",
            "stage_group_id": "stage_screening",
            "position": 1,
            "status_kind": "normal",
            "is_terminal": 0
          }
        ]
      },
      "timeline": [
        {
          "id": "evt_xxx",
          "event_type": "system",
          "message": "Candidate Test Candidate applied through website for Customer Support Specialist",
          "actor_type": "system",
          "actor_name": null,
          "created_at": "2026-01-11T11:10:22.012Z",
          "from_status_name": null,
          "to_status_name": "Applied"
        },
        {
          "id": "evt_yyy",
          "event_type": "status_change",
          "message": "Status set to Applied",
          "actor_type": "system",
          "actor_name": null,
          "created_at": "2026-01-11T11:10:22.013Z",
          "from_status_name": null,
          "to_status_name": "Applied"
        }
      ]
    }

    Frontend Notes#

    Render pipeline visually (columns with active highlight)
    Render timeline chronologically
    Internal-only fields are already excluded

    🧠 Guarantees#

    ✔ All endpoints are stable
    ✔ No breaking changes without /v3
    ✔ Field names will not change
    ✔ HTML fields are safe to render
    ✔ Timeline is append-only
    ✔ Tracking token is unguessable and secure

    🏁 Contract Status#

    Frontend API Contract: LOCKED & FINAL
    You can now:
    Hand this document to WordPress / frontend developers
    Begin UI/UX implementation immediately
    Build Careers pages with confidence

    Next steps (optional):
    Start Careers frontend UI
    Add rate limiting and caching
    Plan Admin Dashboard phase
    Built with