Introduction
Relaxx offers several API Endpoints, for clients / suppliers or partners. In this overview, you can find most of our JSON/REST APIs and how to access them.
Partner-API v1: General
In the current implementation of this feature, the following objects will be created & actions will be triggered if this call is successful:
- a client & contact is created with the supplied data (if not already found in the DB)
- an order is created, containing the supplied products
- a multiposting is created containing the supplied products
- a job-posting and, if a relaxx templateId is provided, the jobPosting and multiposting get connected to that template in relaxx, else a one-time-use layoutTemplate is created and connected to the multiposting
- optional: the supplied address & geopoint is added to the jobPosting
- a task is created for a raven51 employee to further process the multiposting
The data you send is synchronously imported and saved while the actual processing and therefore creation of data mentioned above is handled asynchronously. For status updates on Postings and Multipostings your relaxx contact can configure a webhook for you.
Partner-API v1: Authentication
The current version of this API supports only Basic-Auth. You will receive a login from your relaxx contact person. It is mandatory that you provide your login data via the Authorization header in each request as described here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication#basic_authentication_scheme.
Partner-API v1: Endpoints
Currently the following endpoints are available for use:
GET {baseURL}/public/{uuid}/api/v1/partner/products
GET {baseURL}/public/{uuid}/api/v1/partner/contracts
GET {baseURL}/public/{uuid}/api/v1/partner/calculatePrice
POST {baseURL}/public/{uuid}/api/v1/partner/orderJobPostings
GET {baseURL}/public/{uuid}/api/v1/partner/orderStatus
POST {baseURL}/public/{uuid}/api/v1/partner/markAsOffline
products
Endpoint: GET /api/v1/partner/products
This endpoint gives you access to a custom list of products depending on your usecase. The list is necessary to be able to place orders by using the orderJobPostings endpoint.
Params
Name | Type | Required? |
---|---|---|
_contractSpecId | long | no |
Possible Status Response values
Status Value | Status Name | Description |
---|---|---|
0 | Editing | Product is currently in Edit-Mode and might be changed. |
1 | Active | Product is active and can be used without any concern. |
2 | Disabled | Product is disabled and cannot be used. |
3 | Fulfilled | Product contingent has been reached and therefore cannot be used anymore. |
4 | Expired | Product has expired and therefore cannot be used anymore. |
5 | Fulfilled & Expired | see status 3 and 4. |
6 | No Processing | No Processing. |
curl -X GET "https://demo.relaxx.center/public/{uuid}/api/v1/partner/products" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Sample JSON Response Body
{
"aggregations": {},
"list": [
{
"runtimeCascading": 90,
"publicLogoSrc": null,
"publicName": "campusanzeigen.net / jobstart standard / 3 Monate, Text+Logo!",
"description": "",
"client": {
"name": "campusanzeigen.net GmbH",
"id": 11877
},
"categories": [
],
"priceSingleSale": null,
"id": "18693",
"priceCascading": 400.0
}
],
"total": 5
}
contracts
Endpoint: GET /api/v1/partner/contracts
Returns available contracts and their repective variant / position group template data.
curl -X GET "https://demo.relaxx.center/public/{uuid}/api/v1/partner/contracts" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Params
Name | Type | Required? |
---|---|---|
clientIds | long[] | no |
Sample JSON Response Body
{
"aggregations": {},
"list": [
{
"number": "R123-0000001",
"billingPositionGroupTemplates": [
{
"name": "Positionsgruppe 1",
"id": 1234,
"totalPriceCustomer": 2.352,00,
"totalPricePartner": 1.999,20,
"totalListingPrice": 5041.0,
"products": [
{
"name": "monster.de",
"metaFields": {
"description": ""
},
"id": 1234,
"partnerApiLogoSrc": "https://somelink.de"
}
]
}
],
"client": {
"name": "your company",
"id": 123
},
"validDateStart": 1640991600000,
"id": "12",
"type": "priceAgreement",
"validDateEnd": 1672527599000,
"expectedPurchaseQuantity": 50,
"products": [
{
"statusText": "ACTIVE",
"name": "monster.de",
"metaFields": {
"description": ""
},
"id": 12345,
"priceSingleSale": 123.0,
"partnerApiLogoSrc": "https://somelink.de",
"status": 1
}
]
}
],
"total": 1
}
calculatePrice
Endpoint: GET /api/v1/partner/calculatePrice
Calculates a price based on the provided products. Product ids that need to be provided can be found in the result of the products endpoint. See Products
curl -X GET "https://demo.relaxx.center/public/{uuid}/api/v1/partner/calculatePrice?productIds={id1}&productIds={id2}" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Sample JSON Response Body
{
"price": 1234.0,
"priceWithTax": 2345.0
}
Params
Name | Type | Required? |
---|---|---|
productIds | long[] | yes |
orderJobPostings
Endpoint: POST /api/v1/partner/orderJobPostings
With this endpoint you can place an order with the relaxx system. Usually orders are processed asynchronously. You can however use the param instantProcessing
to make it sync, which also influences the data that is returned on successful processing. For post body see OrderData.
curl -X POST "https://demo.relaxx.center/api/v1/partner/orderJobPostings" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Sample JSON Request Body
{
"externalId": "123-1234-56789",
"jobPostings": [
{
"externalId": "f7dbc5b8-2a39-11eb-8813-02428677322c",
"title": "IT-Administrator (m/w/d)",
"comment": "Test comment",
"applyUrl": "https://test.com/applyHere",
"applyEmail": "hr@testfirma.com",
"htmlUrl": "https://test.com/jobPosting",
"templateId": 5672,
"headerImageUrl": "https://test.com/headerImage.png",
"employmentTypes": ["full_time", "contractor"],
"releaseDateBegin": "2022-05-12T06:36:26+0000",
"releaseDateEnd": "2022-08-12T06:36:26+0000",
"productIds": [1234, 1235, 1236],
"jobClient": {
"externalId": "123a485",
"name": "Testcompany",
"logoUrl": "https://test.com/logo.png",
"contact": {
"mail": "max.mustermann@partner.com",
"name": "Mustermann",
"nameFirst": "Max",
}
},
"addresses": [
{
"street": "Neue Str.",
"streetNumber": "58A",
"postCode": "89073",
"city": "Ulm",
"country": "Germany",
"latitude": 8.3969365,
"longitude": .9907421
}
],
"dynamicContent": {
"intro": "Musterfirma GmbH ist ein mittels...." ,
"offerLabel": "Wir bieten" ,
"offerContent": "\<ul\>\<li\>Point 1 \</li\> ....",
"profileLabel": "Dein Profil" ,
"profileContent": "\<ul\>\<li\>Point 1 \</li\> ....",
"tasksLabel": "Dein Aufgaben" ,
"tasksContent": "\<ul\>\<li\>Point 1 \</li\> ....",
"closing": "Wir freuen uns auf ..."
},
"salary": {
"baseFrom": 42000,
"baseTo": 142000,
"currency": "EUR",
"timeUnit": "YEAR"
},
"applyContact": {
"mail": "max.mustermann@partner.com",
"name": "Mustermann",
"nameFirst": "Max",
}
}
]
}
Sample JSON Response Body (Async)
{
"message": "Successfully received order request for externalId 123-1234-56789"
}
Sample JSON Response Body (Sync)
{
"message": "Successfully received order request for externalId 123-1234-56789",
"orderNumber": "R123-1234567",
"orderId": 123,
"totalPriceWithTax": 2345.78,
"totalPrice": 1234.56,
"pdf": "https://somelink.de"
}
Params
Name | Type | Required? |
---|---|---|
instantProcessing | boolean | no |
Order Data
Main order object and entry point for order post body. Holds necessary information to process an order and generate respective objects.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
externalId | String | "815aa2albc" | yes | Added as externalId to the internal order object, needs to be unique for each order |
billingPurchaseOrderNumber | String | "815aa2albc" | no | will set the field "RE-PO-Nr" in the Deal |
contractClient | BillableClient | Go to BillableClient Data | no | Used for invoicing if present, else partner is invoiced. |
billingClient | BillableClient | Go to BillableClient Data | no | Used for invoicing if present, falls back to contract client if present, else partner is invoiced. |
jobPostings | JobPosting[] | Go to JobPosting Data | yes | Used to generate internal objects used to publish posting with job portals. schema.org:JobPosting |
Contact Data
Contact person object. Used for invoice address in case of contractClient or communication purposes in case of jobClient. Will be created if lookup fails.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
externalId | String | "2-133700fd1" | no | used for lookup, uses mail if not present |
String | "max.mustermann@partner.com" | yes | used for lookup, if externalId not present | |
nameFirst | String | "Max" | only for new users | First name for newly created contact |
name | String | "Mustermann" | only for new users | Last name for newly created contact |
phoneNumber | String | "+49 69 1235456" | no | Phone number of contact |
Client Data
Company object. JobPosting will be published for this.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
externalId | String | "2-133700-1" | yes | finds or creates a Relaxx-Client object for the job posting & for invoicing |
name | String | "TEST Testfirma" | only for new clients | Name for the newly created Client schema.org:name |
logoUrl | String | "https://test.com/logo.png" | only for new clients | Valid URL path to a png or jpg file schema.org:logo |
address | Address | Go to Address Data | no | |
contact | Contact | Go to Contact Data | yes (jobClient only) |
Billable Client Data extends Client Data
Advanced company object. Contains additional fields for invoicing.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
taxId | String | "l2/345/67890" | no | used for invoicing |
vatId | String | "DE999999999" | no | used for invoicing |
JobPosting Data
Actual posting data that will be posted with a job portal.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
externalId | String | "f7dbc5b8-2a39-11eb-8813-02428677322c" | yes | unique reference per posting. |
comment | String | "Test Kommentar" | no | Adds a comment for the processing person. |
title | String | "IT-Administrator (m/w/d)" | yes | schema.org:title |
subtitle | String | "befristet auf 12 Monate" | no | |
applyUrl | String | "https://test.com/applyHere" | yes (conditionally) | used for posting applications, alternative applyEmail schema.org:url |
applyEmail | String | "hr@testfirma.com" | yes (conditionally) | alternative to applyUrl, if both are missing the order is rejected |
htmlUrl | String | "https://test.com/jobPosting" | yes | used for posting applications, alternative applyEmail |
templateId | Long | "567" | no | used to link jobposting to a template in relaxx |
headerImageUrl | String | "https://test.com/headerImage.png" | no | if supplied, will be displayed for stepstone postings at the top of the html |
employmentTypes | String[] | ["full_time", "contractor"] | no | for allowed values, see https://developers.google.com/search/docs/data-types/job-posting schema.org:employmentType |
releaseDateBegin | DateTime | "2022-05-12T06:36:26+0000" | no | Needs to be now or in the future. If not supplied, assumed to be NOW schema.org:datePosted |
releaseDateEnd | DateTime | "2022-08-12T06:36:26+0000" | no | if not supplied, assumed to be releaseDateBegin+productRuntime schema.org:validThrough |
productIds | Long[] | [1234, 1235, 1236] | yes (conditionally) | at least one productId is required if no groupTemplateId is provided. Can't be used in conjunction with groupTemplateId. These are product ids from relaxx. See Products |
groupTemplateId | Long | 1234 | yes (conditionally) | required if no productId is provided. Can't be used in conjunction with productIds. Ids are provided via contracts. See Contracts |
addresses | Address[] | Go to Address Data | no | Used as job location. schema.org:jobLocation |
dynamicContent | JobDynamicContent | Go to JobDynamicContent Data | no | |
salary | Salary | Go to Salary Data | no | schema.org:MonetaryAmount |
jobClient | Client | Go to Client Data | yes | Company the jobPosting is for. schema.org:hiringOrganization |
applyContact | Contact | Go to Contact Data | no | Used to get the Application Contact information when using a templateId |
Salary Data
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
baseFrom | Long | 42000 | no | The lower value of the salary schema.org:minValue |
baseTo | Long | 142000 | no | The upper value of the salary schema.org:maxValue |
currency | String | "EUR" | no | The currency in which the monetary amount is expressed. Use standard formats: ISO 4217 currency format e.g. "USD" or "EUR" schema.org:currency |
timeUnit | String | "YEAR" | no | The timeUnit in which the monetary amount is calculated. Available values are 'HOUR','DAY','WEEK','MONTH','YEAR' |
Address Data
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
street | String | "Neue Str." | no | The Street Name excluding the number schema.org:streetAddress (partial) |
streetNumber | String | "58A" | no | The Street Number schema.org:streetAddress (partial) |
postCode | String | "89073" | no | The Postal Code, can include letters and numbers schema.org:postalCode |
city | String | "Ulm" | no | The city name schema.org:addressLocality |
country | String | "Germany" | no | The country name schema.org:addressCountry |
latitude | Float | 48.3969365 | no | if supplied, needs to be valid latitude value schema.org:latitude |
longitude | Float | 9.9907421 | no | if supplied, needs to be valid longitude value schema.org:longitude |
JobDynamicContent Data
The JobDynamicContent is used for stepstone and other adaptive-design products. They should only contain valid HTML or raw text data. Note: it is not allowed to enter apply-URL-Links in these HTML fragments, this is disallowed by Stepstone & co.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
intro | String/HTML | "Musterfirma GmbH ist ein mittels...." | no | schema.org:employerOverview |
offerLabel | String/HTML | "Wir bieten" | no | |
offerContent | String/HTML | "<ul><li>Point 1 </li> ...." | no | schema.org:jobBenefits |
profileLabel | String/HTML | "Dein Profil" | no | |
profileContent | String/HTML | "<ul><li>Point 1 </li> ...." | no | schema.org:qualifications |
tasksLabel | String/HTML | "Dein Aufgaben" | no | |
tasksContent | String/HTML | "<ul><li>Point 1 </li> ...." | no | schema.org:responsibilities |
closing | String/HTML | "Wir freuen uns auf ..." | no | |
contact | String/HTML | "<p>Testcompany &<br\/>Co. KG<br />HR Manager<br />Max Mustermann..." | no |
orderStatus
Endpoint: GET /api/v1/partner/orderStatus
Returns a status of objects connected to an order.
curl -X GET "https://demo.relaxx.center/public/{uuid}/api/v1/partner/orderStatus?orderNumber={orderNumber}&externalId={externalId}" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Sample JSON Response Body
{
"offers": [
{
"status": 6,
"statusText": "ORDERED",
"totalPriceWithTax": 123.45,
"totalPrice": 234.56,
"products": [
{
"id": "12345",
"name": "stepstone"
},
{
"id": "12346",
"name": "monster.de"
}
],
"pdfLink": "https://somelink.de"
}
],
"order": {
"status": 6,
"statusText": "ORDERED",
"totalPriceWithTax": 123.45,
"totalPrice": 234.56,
"products": [
{
"id": "12345",
"name": "stepstone"
},
{
"id": "12346",
"name": "monster.de"
}
],
"pdfLink": "https://somelink.de"
},
"invoices": [
{
"status": 3,
"statusText": "SENT",
"totalPrice": 123.45,
"totalPriceWithTax": 234.56,
"products": [
{
"id": "12345",
"name": "stepstone"
},
{
"id": "12346",
"name": "monster.de"
}
],
"pdfLink": "https://somelink.de"
}
],
"multipostings": [
{
"id": "1234",
"orderNumber": "R123-4567890A",
"status": 1,
"statusText": "IN_PROGRESS",
"releaseDateEnd": "20233-01-01T10:00:00",
"releaseDateBegin": "20233-01-01T10:00:00"
}
],
"postings": [
{
"id": "1234",
"name": "stepstone",
"multipostingId": 1234,
"orderNumber": "R123-4567890A",
"releaseDateEnd": "20233-01-01T10:00:00",
"releaseDateBegin": "20233-01-01T10:00:00",
"status": 0,
"statusText": "Offen"
},
{
"id": "1235",
"name": "monster.de",
"multipostingId": 1234,
"orderNumber": "R123-4567890A",
"releaseDateEnd": "20233-01-01T10:00:00",
"releaseDateBegin": "20233-01-01T10:00:00",
"status": 0,
"statusText": "Offen"
}
]
}
Params
Name | Type | Required? |
---|---|---|
orderNumber | string | yes (if externalId is not provided) |
externalId | string | yes (if orderNumber is not provided) |
statistic
Endpoint: GET /api/v1/partner/statistic
Returns a status of objects connected to an order.
curl -X GET "https://demo.relaxx.center/public/{uuid}/api/v1/partner/statistic" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Sample JSON Response Body
{
"clicksPerProduct":[
{
"id": 1047247,
"name": "Traffic Network",
"postingId": 2134215,
"multipostingId": 1338855,
"state": 1,
"clicksTotal": 8,
"clicksPerDay":[{"key": 1713139200000, "value": 0 }, {"key": 1713225600000, "value": 0…],
"clicksApplicationRoute": 7
},
{"id": 1047231, "name": "stepstone.de / Pro / 30 Tage inkl. Refresh, individuelles Branding", "postingId": 2134217, "multipostingId": 1338855,…},
{"id": 1047253, "name": "stellenonline.de / Premium / 60 Tage", "postingId": 2134219, "multipostingId": 1338855,…}
],
"clicksApplicationRoute":7
}
Params
Name | Type | Required? | Value |
---|---|---|---|
externalOrderId | string | yes | - |
jobPostingId | string | yes | - |
includedAggs | string | yes | "clicksPerProduct" |
markAsOffline
Endpoint: POST /api/v1/partner/markAsOffline
Creates an internal Task for the raven51 staff to set the Multipostings related to the externalIds provided in the body to the status Offline Early
.
Name | Type | Example | Required? | Purpose / Note |
---|---|---|---|---|
externalIds | String[] or Long[] | [23803, 46599, 76389] | yes | unique reference per postings that will be set to offline early |
curl -X POST "https://demo.relaxx.center/public/{uuid}/api/v1/partner/markAsOffline" -H "Authorization:YOUR_BASE64_ENCODED_PASSWORD"
Sample JSON Response Body
{
"externalIds": ["123123-abc-123l2a121", "123123-abc-123l2a122", "123123-abc-123l2a123"]
}
Partner-API v1: Status Hook
Sample JSON Body
{
"orderId": "2020-11-19-1-8166_TEST1",
"orderNumber": "R232-0028502",
"items": [
{
"jobPostingId": "f7dbc5b8-2a39-11eb-8813-02428677322c",
"multipostingId": 123,
"multipostingStatus": "ordered",
"releaseDateEnd": "20233-01-01T10:00:00",
"releaseDateBegin": "20233-01-01T10:00:00",
"productId": "22344",
"postingId": "123",
"status": "open"
},
{
"jobPostingId": "f7dbc5b8-2a39-11eb-8813-02428677322c",
"multipostingId": 123,
"multipostingStatus": "ordered",
"releaseDateEnd": "20233-01-01T10:00:00",
"releaseDateBegin": "20233-01-01T10:00:00",
"productId": "421337",
"postingId": "124",
"status": "ordered"
},
{
"jobPostingId": "f7dbc5b8-2a39-11eb-8813-02428677322c",
"multipostingId": 123,
"multipostingStatus": "ordered",
"releaseDateEnd": "20233-01-01T10:00:00",
"releaseDateBegin": "20233-01-01T10:00:00",
"productId": "22346",
"postingId": "125",
"status": "approvedOnline"
}
]
}
In order to use this feature, you need to provide a url which will be called on certain events. Currently the status hook is triggered whenever the status of at least one out of two internal objects changes. It sends out an http-request which you will need to confirm with a status code 200. In case you respond with anything else but 200 or there's is some other error, there will be no retry handling and you will miss the current status change.
The following item statuses will be transferred:
Status | Description |
---|---|
open | Item is currently prepared to be ordered with the respective job board. |
ordered | Item has been ordered with the respective job board. |
unapprovedOnline | Item is online by release date. |
approvedOnline | Item was confirmed to be online via URL. |
completed | Item publishing time has been expired. |
earlyOffline | Item has been taken offline before actual release date. |
canceled | Item has been canceled w/o any costs. |
canceledPaid | Item has been canceled. |
Partner-API v1: FAQs
How can a job-posting be delayed?
if you send a date in releaseDateBegin, this date will be used to delay the jobPosting as needed.
Can we post Stepstone postings without fragments?
No, without proper fragments Stepstone cannot be used for posting, or you will be contacted by a Raven51 employee for clarification.
What address will be used if no address is given?
???