Documentation

Partner Integration API

How to use Jobstream partner feed, clicks, and application endpoints.

Introduction

Use this API to fetch creator XML feeds and track partner-attributed clicks and applications.

Base URL

https://production-api.jobstream.co

Authentication

All /partner/* endpoints require:

  • Header: x-api-key: <partner_key>

Accepted keys are configured server-side:

  • PARTNER_INTEGRATION_API_KEY
  • PARTNER_INTEGRATION_E2E_API_KEY (optional, for test environments)
  • SENDERCIRCLE_API_KEY (legacy compatibility)

If key is missing or invalid, API returns 401 Unauthorized.

Core Concepts

creator_handle

Parent creator handle from Jobstream profiles.handle.

sub_id

Partner attribution ID in the format:

<creator_handle>-<suffix>

Example:

  • creator_handle: jiloma
  • sub_id: jiloma-rthgip

E2E/Test mode

If backend has PARTNER_INTEGRATION_E2E=true, then sub_id values containing -e2e- are allowed without requiring a real sub-profile.

Test run correlation

Optional header:

  • x-partner-test-run-id: <run-id>

Use this to correlate click/application events from test runs.


Endpoint: Get XML Feed

GET /partner/feed/:handle/xml

Returns XML feed for the parent creator.

Query params

  • sub_id (optional): validates partner sub attribution context

Example

API_BASE="https://production-api.jobstream.co"
API_KEY="replace-with-partner-key"
CREATOR_HANDLE="jiloma"
SUB_ID="jiloma-e2e-smoke"

curl -sS -X GET "$API_BASE/partner/feed/$CREATOR_HANDLE/xml?sub_id=$SUB_ID" \
  -H "x-api-key: $API_KEY"

Success response

  • 200 OK
  • Content-Type: application/xml; charset=utf-8

Endpoint: Track Click

POST /partner/clicks

Tracks a partner-attributed click into Jobstream job_clicks.

Headers

  • x-api-key (required)
  • x-partner-test-run-id (optional)

Request body

{
  "creator_handle": "jiloma",
  "sub_id": "jiloma-rthgip",
  "job_id": "job_12345",
  "short_code": "abc123xy",
  "source": "partner-campaign"
}

Curl example

API_BASE="https://production-api.jobstream.co"
API_KEY="replace-with-partner-key"
TEST_RUN_ID="partner-smoke-001"

curl -sS -X POST "$API_BASE/partner/clicks" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $API_KEY" \
  -H "x-partner-test-run-id: $TEST_RUN_ID" \
  -d '{
    "creator_handle": "jiloma",
    "sub_id": "jiloma-rthgip",
    "job_id": "job_12345",
    "short_code": "abc123xy",
    "source": "partner-campaign"
  }'

Example response

{
  "id": "2de8f4f4-7d64-4ef3-b27f-b5b50f3d8e9c",
  "kind": "job_click",
  "creator_handle": "jiloma",
  "sub_id": "jiloma-rthgip",
  "job_id": "job_12345",
  "partner_test_run_id": "partner-smoke-001"
}

Endpoint: Track Application

POST /partner/applications

Tracks a partner-attributed application event into Jobstream rxevents and triggers partner webhook if configured.

Headers

  • x-api-key (required)
  • x-partner-test-run-id (optional)

Request body

{
  "creator_handle": "jiloma",
  "sub_id": "jiloma-rthgip",
  "job_id": "job_12345",
  "applicant_email": "candidate@example.com",
  "applicant_first_name": "Alex",
  "applicant_last_name": "Rivera"
}

Curl example

API_BASE="https://production-api.jobstream.co"
API_KEY="replace-with-partner-key"
TEST_RUN_ID="partner-smoke-001"

curl -sS -X POST "$API_BASE/partner/applications" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $API_KEY" \
  -H "x-partner-test-run-id: $TEST_RUN_ID" \
  -d '{
    "creator_handle": "jiloma",
    "sub_id": "jiloma-rthgip",
    "job_id": "job_12345",
    "applicant_email": "candidate@example.com",
    "applicant_first_name": "Alex",
    "applicant_last_name": "Rivera"
  }'

Example response

{
  "id": "85dfcb4f-0f58-4613-a022-03e17cd5fc68",
  "kind": "rx_event",
  "creator_handle": "jiloma",
  "sub_id": "jiloma-rthgip",
  "job_id": "job_12345",
  "partner_test_run_id": "partner-smoke-001"
}

JavaScript Example (Axios)

import axios from "axios";

const api = axios.create({
  baseURL: "https://production-api.jobstream.co",
  headers: {
    "x-api-key": process.env.PARTNER_API_KEY!,
    "Content-Type": "application/json",
  },
});

const creator_handle = "jiloma";
const sub_id = "jiloma-e2e-smoke";
const job_id = "job_12345";
const testRunId = "partner-smoke-001";

async function runPartnerFlow() {
  const feedRes = await api.get(`/partner/feed/${creator_handle}/xml`, {
    params: { sub_id },
  });
  console.log("Feed status:", feedRes.status);

  const clickRes = await api.post(
    "/partner/clicks",
    {
      creator_handle,
      sub_id,
      job_id,
      short_code: "abc123xy",
      source: "partner-campaign",
    },
    { headers: { "x-partner-test-run-id": testRunId } }
  );
  console.log("Click:", clickRes.data);

  const appRes = await api.post(
    "/partner/applications",
    {
      creator_handle,
      sub_id,
      job_id,
      applicant_email: "candidate@example.com",
      applicant_first_name: "Alex",
      applicant_last_name: "Rivera",
    },
    { headers: { "x-partner-test-run-id": testRunId } }
  );
  console.log("Application:", appRes.data);
}

runPartnerFlow().catch((err) => {
  console.error(err.response?.status, err.response?.data || err.message);
});

Error Reference

401 Unauthorized

  • Missing or invalid x-api-key

400 Bad Request

Common causes:

  • creator_handle does not exist
  • sub_id does not match <creator_handle>-<suffix>
  • sub_id is not a known profile handle (when not in E2E bypass mode)
  • short_code does not map to a creator job for that creator (click tracking)

Data Mapping

Clicks (POST /partner/clicks)

Stored in job_clicks with partner attribution fields:

  • cid
  • sub_id
  • click_source
  • query_string (includes test run ID if provided)

Applications (POST /partner/applications)

Stored in rxevents:

  • rxp (parent handle)
  • sub_id (sub attribution)
  • client_id (partner:application)
  • job_id

Optional Outbound Webhook

If configured, application events are forwarded to partner webhook.

Environment variables:

  • PARTNER_APPLICATION_WEBHOOK_URL
  • PARTNER_APPLICATION_WEBHOOK_API_KEY (optional)