For developers

REST API documentation

Integrate Jobriver seamlessly into your ATS, HR system or your own application with our powerful REST API.

Request API access

Overview

The Jobriver REST API enables the programmatic management of your job listings. Integrate Jobriver into your ATS, HR system or your own applications.

RESTfulGET, POST, PUT, DELETE
JSONRequest & Response
v1Versioned
60/minRate limit (default)

Authentication

All API requests require a valid API key in the header:

X-API-Key: jrv_abc123def456...

Permissions

API keys can be configured with granular permissions:

PermissionDescription
readList and retrieve jobs, categories and technologies
createCreate new jobs
updateEdit existing jobs
deleteDelete jobs
Security notes
  • Never store API keys in front-end code
  • Use environment variables for keys
  • Enable IP whitelisting in the dashboard
  • After 5 failed attempts: 1 min. block

Base URL & endpoints

https://jobriver.de/api/v1/
MethodEndpointDescriptionPermission
GET/statusAPI status & key info-
GET/jobsList jobsread
GET/jobs/{id}Retrieve a single jobread
POST/jobsCreate a jobcreate
PUT/PATCH/jobs/{id}Update a jobupdate
DELETE/jobs/{id}Delete a jobdelete
GET/categoriesList categoriesread
GET/technologiesList technologiesread

Rate Limiting

Default: 60 requests per minute (expandable)

Response Headers

X-RateLimit-LimitMaximum requests per minute
X-RateLimit-RemainingRemaining requests
X-RateLimit-ResetUnix timestamp for reset
X-Request-IdUnique request ID (for support)

When exceeded: HTTP 429 with Retry-After header.

Endpoints in detail

GET /api/v1/status

Returns API status and information about the API key used.

Request
curl -X GET "https://jobriver.de/api/v1/status" \
  -H "X-API-Key: jrv_abc123..."
Response (200 OK)
{
  "success": true,
  "data": {
    "api_version": "v1",
    "status": "ok",
    "key": {
      "name": "Production API Key",
      "prefix": "jrv_abc1",
      "status": "active",
      "permissions": ["read", "create", "update", "delete"],
      "created_at": "2024-01-15T10:00:00Z",
      "expires_at": null
    },
    "company": {
      "id": 42,
      "name": "TechStartup GmbH",
      "slug": "techstartup-gmbh"
    },
    "limits": {
      "rate_limit": {
        "requests_per_minute": 60,
        "remaining": 58,
        "reset": 1707134520
      },
      "job_limit": {
        "limit": 100,
        "current_active_jobs": 23,
        "unlimited": false
      }
    },
    "usage": {
      "requests_total": 4523,
      "requests_today": 127,
      "jobs_created": 45,
      "last_request_at": "2024-02-05T14:30:00Z",
      "last_request_ip": "192.168.1.100"
    },
    "ip_whitelist": ["192.168.1.0/24"],
    "server_time": "2024-02-05T14:35:00+01:00"
  },
  "meta": {
    "rate_limit": {
      "limit": 60,
      "remaining": 58,
      "reset": 1707134520
    }
  }
}

GET /api/v1/jobs

Lists all of the company's jobs with pagination and filter options.

Query Parameter
ParameterTypeDefaultDescription
pageinteger1Page number (min: 1)
per_pageinteger20Items per page (max: 100)
is_activeboolean-Filter: true or false
category_idinteger-Filter by category ID
searchstring-Search in title/description (max: 100 characters)
Request
curl -X GET "https://jobriver.de/api/v1/jobs?page=1&per_page=10&is_active=true" \
  -H "X-API-Key: jrv_abc123..."
Response (200 OK)
{
  "success": true,
  "data": {
    "jobs": [
      {
        "id": 123,
        "slug": "senior-backend-developer",
        "title": "Senior Backend Developer",
        "description": "We are looking for an experienced backend developer...",
        "requirements": "At least 5 years of experience with PHP...",
        "benefits": "Flexible working hours, remote option...",
        "location": "Berlin",
        "latitude": 52.52000000,
        "longitude": 13.40500000,
        "location_type": "hybrid",
        "employment_type": "fulltime",
        "experience_level": "senior",
        "category": {
          "id": 5,
          "name": "Software Development",
          "slug": "software-development"
        },
        "salary": {
          "min": 65000,
          "max": 85000,
          "currency": "EUR"
        },
        "technologies": [
          {"id": 1, "name": "PHP", "slug": "php", "category": "backend"},
          {"id": 2, "name": "Laravel", "slug": "laravel", "category": "backend"},
          {"id": 3, "name": "MariaDB", "slug": "mariadb", "category": "database"}
        ],
        "apply_type": "internal",
        "apply_url": null,
        "apply_email": null,
        "is_featured": false,
        "is_active": true,
        "applications_count": 12,
        "start_date": "2024-03-01",
        "languages_required": ["Deutsch", "Englisch"],
        "soft_skills": ["Teamfähigkeit", "Kommunikation"],
        "published_at": "2024-02-01T10:00:00Z",
        "expires_at": null,
        "created_at": "2024-02-01T09:30:00Z",
        "updated_at": "2024-02-05T14:00:00Z"
      }
    ],
    "pagination": {
      "current_page": 1,
      "per_page": 10,
      "total": 23,
      "total_pages": 3
    }
  },
  "meta": {
    "rate_limit": { "limit": 60, "remaining": 57, "reset": 1707134520 }
  }
}

GET /api/v1/jobs/{id}

Returns a single job.

Request
curl -X GET "https://jobriver.de/api/v1/jobs/123" \
  -H "X-API-Key: jrv_abc123..."
Response

Single job object (same structure as in the listing).

POST /api/v1/jobs

Creates a new job.

Required fields
FieldTypeValidation
titlestring3-255 characters
descriptionstringmin. 50 characters
locationstringmax. 255 characters
Optional fields
FieldTypeAllowed values
requirementsstringmax. 65535 characters
benefitsstringmax. 65535 characters
location_typeenumonsite, remote, hybrid
employment_typeenumfulltime, parttime, contract, freelance, internship
experience_levelenumjunior, mid, senior, lead, any
category_idintegerValid category ID
latitudefloat-90 to 90
longitudefloat-180 to 180
salary_mininteger0 - 1,000,000 EUR
salary_maxinteger≥ salary_min
technologiesarrayArray of technology IDs
apply_typeenuminternal, external, email
apply_urlstringRequired when apply_type = external
apply_emailstringRequired when apply_type = email
start_datestringFormat: YYYY-MM-DD
languages_requiredarray["Deutsch", "Englisch"]
soft_skillsarray["Teamfähigkeit", ...]
is_featuredbooleanDefault: false
is_activebooleanDefault: true
Request
curl -X POST "https://jobriver.de/api/v1/jobs" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: jrv_abc123..." \
  -d '{
    "title": "Senior Backend Developer",
    "description": "We are looking for an experienced backend developer with at least 5 years of professional experience in PHP. You will work on our core platform and collaborate closely with the front-end team.",
    "location": "Berlin",
    "latitude": 52.52000000,
    "longitude": 13.40500000,
    "location_type": "hybrid",
    "employment_type": "fulltime",
    "experience_level": "senior",
    "category_id": 5,
    "salary_min": 65000,
    "salary_max": 85000,
    "technologies": [1, 2, 3],
    "apply_type": "internal",
    "start_date": "2024-03-15",
    "languages_required": ["Deutsch", "Englisch"],
    "soft_skills": ["Teamfähigkeit", "Kommunikation"],
    "is_active": true
  }'
Response (201 Created)
{
  "success": true,
  "data": {
    "id": 456,
    "slug": "senior-backend-developer-2",
    "title": "Senior Backend Developer",
    ...
  }
}
Validation Error (422)
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Validation failed",
    "details": {
      "errors": {
        "title": "Title must be at least 3 characters",
        "description": "Description must be at least 50 characters",
        "salary_min": "salary_min cannot be greater than salary_max"
      }
    }
  }
}

PUT /api/v1/jobs/{id}

Updates an existing job. Partial updates are possible – only the fields provided are updated.

Request
curl -X PUT "https://jobriver.de/api/v1/jobs/123" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: jrv_abc123..." \
  -d '{
    "salary_min": 70000,
    "salary_max": 90000,
    "is_featured": true
  }'
Response (200 OK)

Returns the updated job object.

DELETE /api/v1/jobs/{id}

Permanently deletes a job. This action cannot be undone.

Request
curl -X DELETE "https://jobriver.de/api/v1/jobs/123" \
  -H "X-API-Key: jrv_abc123..."
Response (200 OK)
{
  "success": true,
  "data": {
    "deleted": true,
    "job_id": 123
  }
}

GET /api/v1/categories

Returns all active categories, sorted by sort order. Useful for looking up valid category_id values when creating jobs.

Query Parameter
ParameterTypeDescription
searchstringSearch in category name (max. 100 characters)
Request
curl -X GET "https://jobriver.de/api/v1/categories" \
  -H "X-API-Key: jrv_abc123..."
Response (200 OK)
{
  "success": true,
  "data": {
    "categories": [
      {
        "id": 1,
        "name": "Software-Entwicklung",
        "slug": "software-entwicklung",
        "icon": "code",
        "description": "Backend, Frontend, Fullstack...",
        "job_count": 42
      },
      {
        "id": 2,
        "name": "Data Science",
        "slug": "data-science",
        "icon": "bar-chart",
        "description": "Machine Learning, Analytics...",
        "job_count": 15
      }
    ],
    "total": 2
  }
}

GET /api/v1/technologies

Returns all technologies, sorted by name. Useful for looking up valid technology IDs when creating jobs.

Query Parameter
ParameterTypeDescription
categoryenumFilter: language, framework, database, devops, cloud, tool, other
trendingbooleanFilter: trending technologies only (true)
searchstringSearch in technology name (max. 100 characters)
Request
curl -X GET "https://jobriver.de/api/v1/technologies?category=framework&trending=true" \
  -H "X-API-Key: jrv_abc123..."
Response (200 OK)
{
  "success": true,
  "data": {
    "technologies": [
      {
        "id": 2,
        "name": "Laravel",
        "slug": "laravel",
        "category": "framework",
        "job_count": 28,
        "is_trending": true
      },
      {
        "id": 7,
        "name": "React",
        "slug": "react",
        "category": "framework",
        "job_count": 35,
        "is_trending": true
      }
    ],
    "total": 2
  }
}

Data model

Job object

FieldTypeDescription
idintegerUnique job ID
slugstringURL-friendly identifier
titlestringJob title
descriptionstringFull description
requirementsstring|nullRequirements
benefitsstring|nullBenefits
locationstringWork location
latitudefloat|nullLatitude (-90 to 90)
longitudefloat|nullLongitude (-180 to 180)
location_typeenumonsite, remote, hybrid
employment_typeenumfulltime, parttime, etc.
experience_levelenumjunior, mid, senior, lead, any
categoryobject{id, name, slug}
salaryobject{min, max, currency}
technologiesarray[{id, name, slug, category}]
apply_typeenuminternal, external, email
is_activebooleanPublication status
is_featuredbooleanFeatured
applications_countintegerNumber of applications
created_atdatetimeISO 8601 format
updated_atdatetimeISO 8601 format

Category object (GET /categories)

FieldTypeDescription
idintegerUnique category ID
namestringCategory name
slugstringURL-friendly identifier
iconstring|nullIcon name
descriptionstring|nullCategory description
job_countintegerNumber of active jobs in this category

Technology object (GET /technologies)

FieldTypeDescription
idintegerUnique technology ID
namestringTechnology name
slugstringURL-friendly identifier
categoryenumlanguage, framework, database, devops, cloud, tool, other
job_countintegerNumber of jobs with this technology
is_trendingbooleanWhether the technology is currently trending

Full example (job)

{
  "id": 123,
  "slug": "senior-backend-developer",
  "title": "Senior Backend Developer",
  "description": "We are looking for an experienced backend developer...",
  "requirements": "At least 5 years of experience with PHP...",
  "benefits": "Flexible working hours, remote option...",
  "location": "Berlin",
  "latitude": 52.52000000,
  "longitude": 13.40500000,
  "location_type": "hybrid",
  "employment_type": "fulltime",
  "experience_level": "senior",
  "category": {
    "id": 5,
    "name": "Software Development",
    "slug": "software-development"
  },
  "salary": {
    "min": 65000,
    "max": 85000,
    "currency": "EUR"
  },
  "technologies": [
    {"id": 1, "name": "PHP", "slug": "php", "category": "backend"},
    {"id": 2, "name": "Laravel", "slug": "laravel", "category": "backend"}
  ],
  "apply_type": "internal",
  "apply_url": null,
  "apply_email": null,
  "is_featured": false,
  "is_active": true,
  "applications_count": 12,
  "start_date": "2024-03-01",
  "languages_required": ["Deutsch", "Englisch"],
  "soft_skills": ["Teamfähigkeit", "Kommunikation"],
  "published_at": "2024-02-01T10:00:00Z",
  "expires_at": null,
  "created_at": "2024-02-01T09:30:00Z",
  "updated_at": "2024-02-05T14:00:00Z"
}

Error codes

All errors follow this format:

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Beschreibung des Fehlers",
    "details": {}
  }
}

Authentication (4xx)

CodeHTTPDescription
MISSING_API_KEY401X-API-Key header missing
INVALID_API_KEY403API key invalid or not found
API_KEY_INACTIVE403API key is deactivated
API_KEY_REVOKED403API key has been revoked
API_KEY_EXPIRED403API key has expired
API_KEY_BLOCKED403Temporarily blocked (too many failed attempts)
IP_NOT_ALLOWED403IP not in the whitelist
PERMISSION_DENIED403Missing permission for this action

Rate limiting

CodeHTTPDescription
RATE_LIMIT_EXCEEDED429Too many requests. Observe the Retry-After header.

Validation & resources

CodeHTTPDescription
VALIDATION_ERROR422Input data invalid. Details in errors.
INVALID_JOB_ID400Job ID missing or invalid
JOB_NOT_FOUND404Job not found
JOB_LIMIT_EXCEEDED403Maximum number of active jobs reached
INVALID_REQUEST_BODY400Request body missing or not valid JSON
INVALID_CONTENT_TYPE415Content-Type must be application/json
METHOD_NOT_ALLOWED405HTTP method not allowed

Server errors (5xx)

CodeHTTPDescription
INTERNAL_ERROR500Internal server error
UPDATE_FAILED500Job could not be updated
DELETE_FAILED500Job could not be deleted

Code examples

cURL (Bash)

# Kategorien abrufen
curl -X GET "https://jobriver.de/api/v1/categories" \
  -H "X-API-Key: jrv_abc123..."

# Technologien nach Kategorie filtern
curl -X GET "https://jobriver.de/api/v1/technologies?category=framework&trending=true" \
  -H "X-API-Key: jrv_abc123..."

# Jobs auflisten
curl -X GET "https://jobriver.de/api/v1/jobs?is_active=true&per_page=10" \
  -H "X-API-Key: jrv_abc123..."

# Job erstellen
curl -X POST "https://jobriver.de/api/v1/jobs" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: jrv_abc123..." \
  -d '{"title":"PHP Developer","description":"Description at least 50 characters long...","location":"Berlin"}'

JavaScript (fetch)

const API_KEY = 'jrv_abc123...';
const BASE_URL = 'https://jobriver.de/api/v1';

// Kategorien abrufen
async function getCategories() {
  const res = await fetch(`${BASE_URL}/categories`, {
    headers: { 'X-API-Key': API_KEY }
  });
  const { data } = await res.json();
  return data.categories; // [{id, name, slug, icon, description, job_count}]
}

// Technologien abrufen (mit Filter)
async function getTechnologies(category = null) {
  const params = category ? `?category=${category}` : '';
  const res = await fetch(`${BASE_URL}/technologies${params}`, {
    headers: { 'X-API-Key': API_KEY }
  });
  const { data } = await res.json();
  return data.technologies; // [{id, name, slug, category, job_count, is_trending}]
}

// Jobs abrufen
async function getJobs() {
  const res = await fetch(`${BASE_URL}/jobs?is_active=true`, {
    headers: { 'X-API-Key': API_KEY }
  });
  const { success, data, error } = await res.json();

  if (!success) {
    console.error('API Error:', error.code, error.message);
    return [];
  }
  return data.jobs;
}

// Job erstellen
async function createJob(jobData) {
  const res = await fetch(`${BASE_URL}/jobs`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-API-Key': API_KEY
    },
    body: JSON.stringify(jobData)
  });
  return await res.json();
}

PHP (cURL)

<?php
$apiKey = 'jrv_abc123...';
$baseUrl = 'https://jobriver.de/api/v1';

// Kategorien abrufen
function getCategories(): array {
    global $apiKey, $baseUrl;
    $ch = curl_init("$baseUrl/categories");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"]
    ]);
    $response = json_decode(curl_exec($ch), true);
    curl_close($ch);
    return $response['success'] ? $response['data']['categories'] : [];
}

// Technologien abrufen (optional gefiltert)
function getTechnologies(?string $category = null): array {
    global $apiKey, $baseUrl;
    $url = "$baseUrl/technologies" . ($category ? "?category=$category" : '');
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"]
    ]);
    $response = json_decode(curl_exec($ch), true);
    curl_close($ch);
    return $response['success'] ? $response['data']['technologies'] : [];
}

// Jobs abrufen
function getJobs(): array {
    global $apiKey, $baseUrl;

    $ch = curl_init("$baseUrl/jobs?is_active=true&per_page=20");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ["X-API-Key: $apiKey"]
    ]);

    $response = json_decode(curl_exec($ch), true);
    curl_close($ch);

    return $response['success'] ? $response['data']['jobs'] : [];
}

// Job erstellen
function createJob(array $data): array {
    global $apiKey, $baseUrl;

    $ch = curl_init("$baseUrl/jobs");
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST => true,
        CURLOPT_POSTFIELDS => json_encode($data),
        CURLOPT_HTTPHEADER => [
            "Content-Type: application/json",
            "X-API-Key: $apiKey"
        ]
    ]);

    $response = json_decode(curl_exec($ch), true);
    curl_close($ch);

    return $response;
}

Python (requests)

import requests

API_KEY = 'jrv_abc123...'
BASE_URL = 'https://jobriver.de/api/v1'

headers = {'X-API-Key': API_KEY}

# Kategorien abrufen
categories = requests.get(f'{BASE_URL}/categories', headers=headers).json()
print(f"Kategorien: {categories['data']['total']}")

# Technologien abrufen (z.B. nur Frameworks)
technologies = requests.get(f'{BASE_URL}/technologies', headers=headers, params={
    'category': 'framework',
    'trending': 'true'
}).json()
print(f"Trending Frameworks: {technologies['data']['total']}")

# Jobs abrufen
response = requests.get(f'{BASE_URL}/jobs', headers=headers, params={
    'is_active': 'true',
    'per_page': 20
})
data = response.json()

if data['success']:
    jobs = data['data']['jobs']
    for job in jobs:
        print(f"{job['id']}: {job['title']}")

# Job erstellen
new_job = {
    'title': 'Python Developer',
    'description': 'We are looking for an experienced Python developer with at least 3 years of experience...',
    'location': 'München',
    'location_type': 'remote',
    'employment_type': 'fulltime',
    'salary_min': 55000,
    'salary_max': 75000
}

response = requests.post(
    f'{BASE_URL}/jobs',
    headers={**headers, 'Content-Type': 'application/json'},
    json=new_job
)
result = response.json()
Coming soon
  • Webhooks for application events
  • Batch operations (multiple jobs at once)
  • Retrieve applications via API

Admin API

The Admin API enables authorised administrators to programmatically access internal management functions. It is separate from the company API and uses its own authentication tokens.

Administrators only

The Admin API is intended exclusively for internal use. Admin tokens are created and managed via the admin dashboard at /admin/admin-tokens/.

Authentication

Admin API requests use special admin tokens (prefix jra_) in the header:

X-API-Key: jra_abc123def456...

Difference: company API vs. Admin API

Company APIAdmin API
Prefixjrv_jra_
AccessRegistered companiesAdministrators only
ScopeThe company's own jobsAll internal resources
Base URL/api/v1//api/v1/admin/

Permissions

Admin tokens can be configured with granular permissions:

PermissionDescription
readList and retrieve resources
createCreate new resources
updateEdit existing resources
deleteDelete resources

Base URL & endpoints

https://jobriver.de/api/v1/admin/
MethodEndpointDescriptionPermission
POST/leadsCreate a new leadcreate

Response format

All Admin API responses follow a uniform format:

{
  "success": true,
  "data": { ... },
  "meta": {
    "request_id": "abc123",
    "timestamp": "2026-02-16T12:00:00+01:00"
  }
}

Error format

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Fields \"vorname\" and \"nachname\" are required",
    "details": { ... }
  },
  "meta": {
    "request_id": "abc123",
    "timestamp": "2026-02-16T12:00:00+01:00"
  }
}

Admin: Leads

Create leads programmatically — ideal for forms, ad integrations or CRM imports.

POST /api/v1/admin/leads

Creates a new lead in the internal CRM system.

Required fields

FieldTypeDescription
vornamestringContact's first name
nachnamestringContact's last name

Optional fields

FieldTypeDefaultDescription
emailstringnullEmail address
telefonstringnullPhone number
firmastringnullCompany name
adressestringnullAddress
datum_eingangstring (date)TodayReceipt date in format YYYY-MM-DD
statusstring (enum)neuLead status: neu, wv, termin, angebot, deal, tot
package_idintegernullID of a package from the package management
preisnumbernullPrice in euros (e.g. 499.00)
anzahlinteger1Quantity
rabattnumber0Discount in percent (e.g. 10 for 10%)
notizenstringnullInternal notes on the lead

Status values

ValueMeaning
neuNew lead (default)
wvFollow-up
terminAppointment scheduled
angebotQuote created
dealClosed (deal)
totNot interested
Request — cURL
curl -X POST "https://jobriver.de/api/v1/admin/leads" \
  -H "X-API-Key: jra_abc123..." \
  -H "Content-Type: application/json" \
  -d '{
    "vorname": "Max",
    "nachname": "Mustermann",
    "email": "[email protected]",
    "telefon": "+49 123 456789",
    "firma": "Muster GmbH",
    "status": "neu",
    "datum_eingang": "2026-02-16"
  }'
Response (201 Created)
{
  "success": true,
  "data": {
    "id": 42,
    "lead": {
      "id": 42,
      "vorname": "Max",
      "nachname": "Mustermann",
      "firma": "Muster GmbH",
      "adresse": null,
      "telefon": "+49 123 456789",
      "email": "[email protected]",
      "datum_eingang": "2026-02-16",
      "reminder": null,
      "package_id": null,
      "package_name": null,
      "preis": null,
      "anzahl": 1,
      "rabatt": "0.00",
      "status": "neu",
      "angebot_status": "keine",
      "angebot_pdf_path": null,
      "angebot_nummer": null,
      "notizen": null,
      "created_by": 1,
      "created_at": "2026-02-16 12:00:00",
      "updated_at": "2026-02-16 12:00:00"
    }
  },
  "meta": {
    "request_id": "abc123",
    "timestamp": "2026-02-16T12:00:00+01:00"
  }
}
Request — JavaScript (fetch)
const response = await fetch('https://jobriver.de/api/v1/admin/leads', {
  method: 'POST',
  headers: {
    'X-API-Key': 'jra_abc123...',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    vorname: 'Max',
    nachname: 'Mustermann',
    email: '[email protected]',
    telefon: '+49 123 456789',
    status: 'neu'
  })
});

const result = await response.json();
console.log('Lead erstellt:', result.data.id);
Request — PHP
$ch = curl_init('https://jobriver.de/api/v1/admin/leads');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'X-API-Key: jra_abc123...',
        'Content-Type: application/json'
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'vorname' => 'Max',
        'nachname' => 'Mustermann',
        'email' => '[email protected]',
        'telefon' => '+49 123 456789',
        'status' => 'neu'
    ])
]);

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

$result = json_decode($response, true);
echo "Lead erstellt mit ID: " . $result['data']['id'];
Request — Python
import requests

response = requests.post(
    'https://jobriver.de/api/v1/admin/leads',
    headers={
        'X-API-Key': 'jra_abc123...',
        'Content-Type': 'application/json'
    },
    json={
        'vorname': 'Max',
        'nachname': 'Mustermann',
        'email': '[email protected]',
        'telefon': '+49 123 456789',
        'status': 'neu'
    }
)

result = response.json()
print(f"Lead erstellt mit ID: {result['data']['id']}")

Error responses

HTTP StatusError CodeDescription
400INVALID_BODYRequest body is not valid JSON
401UNAUTHORIZEDMissing or invalid API key
403FORBIDDENToken has no create permission
405METHOD_NOT_ALLOWEDOnly POST is allowed
422VALIDATION_ERRORRequired fields missing or invalid status
429RATE_LIMITEDToo many requests
500CREATION_FAILEDInternal error while creating the lead
Error example (422)
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Fields \"vorname\" and \"nachname\" are required",
    "details": {
      "required": ["vorname", "nachname"]
    }
  },
  "meta": {
    "request_id": "def456",
    "timestamp": "2026-02-16T12:01:00+01:00"
  }
}

Ready to get started?

Register and request your API key.

Get started now