NAV
shell python java

1. Introduction

Congrats you are about to work with the most mobility friendly system:

- Why do dragons sleep during the day?

- So they can fight knights

;-)

Welcome to the API Documentation for Joinup Providers!

Our API allows you to request Joinups (taxis, VTCs and motorcycles) using our API endpoints.

We have language bindings in Shell, Python & Java, but it is up to you to use any programming language (Python, Java, Ruby, Javascript, etc). You will find code examples in the right dark area.

2. Integration types

You can integrate with us in several ways. In this documentation, we will focus on Server to server integration, but you must know that you can connect with us from client to server. In client to server integration the endpoints are the same, almost everything is the same, but for example the AAI (Authentication and authorization infrastructure) is different or we don't need an own push system.

2.1 Client to server

The client can be done in two ways, you can choose between one of them:

- Own development. You can implement web or/and app and connect with this API, yourself

- We create a clone web or/and app with several customization for you. We have already done it several times and will do it like a shot :-)

2.2 Server to server

2.2.1 Where to start?

There are several endpoints in this documentation, but there is only one mandatory endpoint: Create Service. But if do you want do an integration more rich we have another endpoints to use

Following the importance of creating a service will be Cancel service. It is not required, but recommended, for error corrections or cancel service after the request

If your services need to be modified, then you should use the Edit service endpoint

You can use a generic user for the integration or you can use a specific user for every request. So, if you want to request a service to John Smith, you will create (signup) a user for John Smith in our system the first time, and after it you will create a service in our system. If John Smith wants another service, you do not have to create a user the next time. See more info in AAI section.

To track the active services we recommend the Current endpoint. Although we have enable push notifications, polling is highly recommended. We recommend you to call to this endpoint every 30 seconds or one time per minute will be enough for a good feedback of the current services.

2.2.2 Where to continue?

For a deeper integration the Zone endpoint is a good point to follow. Every zone has a different configuration. The configuration is not the same in a big city than in a little city or a town, in the downtown of a city than in the suburbs of a city, in an airport than in another airport...

With Zone endpoint, you can knows the available taxi types (conventionals, six seats, ecos, electrics, high-ends, adapteds, etc), if you can request an immediate service, if there is cost cancellation, if destination is required, min time to request a reservation, etc

But if you want to request only conventional taxis, and you can request them within a reasonable time... Really, this endpoint is not necessary

Also, we recommend you use Places if you want to request services in railstations or airports. But if you are not going to request in these places it is not necessary for you too

If you do not choose the generic user option and your users can change his/her data: first name, last name, phone or even gender. So, you should use Edit profile

To allow us to improve our system, we need feedback. With Vote endpoint we will be notified. If we do not know what we're doing wrong, we won't be able to improve for you :-)

2.2.3 Other endpoints

If you have a solution where endusers signup, so it is possible that you want to use Validates endpoints

We have documented: Services e.g.: to synchronize one time per day (e.g.: a taxi driver was wrong for an amount, and we can update it after finishing the service). Get Profile if you want to get the data we have about a user or Address to save the favorite addresses of the users (e.g.: home, work, etc)

We still have about 20 endpoints undocumented. So, if you need something, please contact us because it is very probably that we have developed it.

3. URLs

Every URL has next path prefix: /api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/

Parameter Description
PROVIDER-SLUG Identifier of your system in our URL path. You can choose it
PLATFORM server
VERSION 3.15.0

4. Configuration provider

We try to adapt to your system and for this reason we have several parameters that we can configure for you in our system.

Parameter Description Recommendation
Name It is only a name. Name of your system
Prefix URL prefix Slugify of name of your system
Enabled It works to disable the integration very quickly. True
Send mail? If you want our system send emails.e.g.: After signup False
Send sms? If you want our system send SMSs.e.g.: After signup False
Available taxi types The taxi types that your users can requests: conventional, six seats, eco, electric car, high-end, screen or adapted e.g.: conventional and six seats
Self-validated phone? If you want that our system validates the phone of your users or if you want that we trust in the validation in your system. True
Self-validated email? If you want that our system validates the e-mail of your users or if you want that we trust in the validation in your system. True
Can passengers vote? If you want that your users can vote your services in our system True
Skip reservation pickup date validation? Our bookings have a minimum time to request. E.g.: No sense requesting a booking for a minute. But if you want we can skip this validation False
Default company Any passenger registered will be added to this company by default. This is for billing. If a passenger belongs to a company, so your system can request a taxi service on credit. This company has a lot of configuration too
Allow companies Your system can register a user of these companies. The difference with the previous attribute is that you can have several companies with different configurations. And you have to set the company of every passenger in the signup endpoint None
Area Your users may only request services in this area None
Association Any service requested by your users will be assigned to the indicated association None
Always services for association True: every service will be for the previous association. False: Only when pickup zone or destination zone will be a zone of this association False

5. Authentication, Authorization & Impersonate

To authorization, use this code when we are creating an user:

curl "api_endpoint_here" \
  -H "Authorization: JWT beep-beep-beep-beep-beep"
import requests

headers = {
    'Authorization': 'JWT beep-beep-beep-beep-beep',
}

response = requests.get('http://api_endpoint_here', headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("api_endpoint_here");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "JWT beep-beep-beep-beep-beep");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

Or use this another code when we are accessing to another endpoint: Authorization with your private token. And Authentication with username (email) or with phone of the user:

curl "api_endpoint_here" \
  -H "Authorization: JWT beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com"
import requests

headers = {
    'Authorization': 'JWT beep-beep-beep-beep-beep',
    'Impersonate': 'foo.bar@example.com',
}

response = requests.get('http://api_endpoint_here', headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("api_endpoint_here");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "JWT beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

Make sure to replace beep-beep-beep-beep-beep with your private token.

Joinup API expects for the token to be included in all API requests to the server in a header that looks like the following:

Authorization: beep-beep-beep-beep-beep

Joinup API expects for the impersonate header to be included in all API requests excepts in signup endpoint. In a header that looks like the following:

Impersonate: foo.bar@example.com

6. Signup

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/signup/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{
      "email":"test@example.com", 
      "first_name":"Test",
      "last_name": "Foo",
      "phone": "+34123456780"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
}

json_data = {
    'email': 'test@example.com',
    'first_name': 'Test',
    'last_name': 'Foo',
    'phone': '+34123456780',
}

response = requests.post(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/signup/',
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/signup/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n      \"email\":\"test@example.com\", \n      \"first_name\":\"Test\",\n      \"last_name\": \"Foo\",\n      \"phone\": \"+34123456780\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

    {
      "is_email_validated": false,
      "is_phone_validated": false,
      "token": "TOKEN"
    }

6.1 HTTP Request

POST https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/signup/

This endpoint creates a new passenger, a new user, for a generic user skip this endpoint

6.2 Signup attributes data

Attribute Description
email If you do not want that we send mails to your users (See configuration provider. So, you can send fake emails, something like this: USER_ID@DOMAIN_PROVIDER ==> user-37812@example.com)
first_name First name of your user.
last_name Last name of your user.
phone Phone contact of your user.

6.3 Signup attributes response

Attribute Description
token Token for integrations client to server. Ignore if your integration is server to server
is_phone_validated At least that you choose "self validate phone" in configuration provider this will be false
is_email_validated At least that you choose "self validate email" in configuration provider this will be false

6.4 Status codes

Status Code Meaning
201 Created
400 Bad Request -- A field is empty or there is any validation error, e.g.: there is another user registered with this phone

7. Validates

These endpoints depend on the configuration provider. These don't make sense if you want to use only a generic user or If you want that we set self-validate email / phone in Configuration provider

7.1 Validate email

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/email/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER" \
  -X PUT \
  -d '{
      "email_code": "1234"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

json_data = {
    'email_code': '1234',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/email/', 
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/email/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n      \"email_code\": \"1234\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

    {"email_code": "1234"}

7.1.1 HTTP Request

PUT https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/email/

This endpoint validates the email of a user. Our system sends an email with a code, you have to call to this endpoint with this value in email_code

7.1.2 Validate email attributes response

Attribute Description
email_code Returns email code when the request had success, otherwise returns a 400 Bad request

7.1.3 Status code

Status Code Meaning
200 OK
400 Bad Request -- The email code is invalid

7.2 Validate phone

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/phone/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER" \
  -X PUT \
  -d '{
      "phone_code": "5678"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

json_data = {
    'phone_code': '5678',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/phone/', 
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/phone/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n      \"phone_code\": \"5678\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

    {"phone_code": "5678"}

7.2.1 HTTP Request

PUT https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/validation/phone/

This endpoint validates the phone of a user. Our system sends a SMS with a code, you have to call to this endpoint with this value in phone_code

7.2.2 Validate email attributes response

Attribute Description
phone_code Returns phone code when the request had success, otherwise returns a 400 Bad request

7.2.3 Success code

Status Code Meaning
200 OK
400 Bad Request -- The phone code is invalid

8. Profile

8.1 Get Profile

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

response = requests.get(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/', 
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

{
  "user": {
    "username": "test@example.com",
    "first_name": "Test",
    "last_name": "Foo"
  },
  "gender": "",
  "image_url": null,
  "dialcode": "+34",
  "phone": "+34 123 456 789",
  "is_phone_validated": true,
  "is_email_validated": true,
  "vote": false,
  "allow_taxi_request_personal": true,
  "allow_taxi_request_company": true,
  "has_personal_credit_card_valid": false,
  "has_employee_credit_card_valid": false,
  "cost_cancellation_required_personal_stripe_enabled": true,
  "cost_cancellation_enabled": true,
  "can_test_request": false,
  "required_personal_credit_card": false,
  "allow_fixed_rate": false,
  "default_way_to_pay": "", 
  "co2_not_emitted": 0,
  "saved_money": 0,
  "can_impersonate": false,
  "employee": null
}

In addition to these fields there are undocumented employee/company fields, "employee" would be a dict

8.1.1 HTTP Request

Get https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/signup/

This endpoint gets the passenger profile. If you want to use only a generic user you should do not use this endpoint

We have the common info to every user (passengers, taxi drivers, Joinup operators, admins, etc) in the User model. And the specific info of a passenger in a Passenger model. For this reason, we have this structure in the json object

8.1.2 Profile attributes response (user)

Attribute Description
username email of your user
first_name First name of your user
last_name Last name of your user

8.1.3 Profile attributes response (passenger)

Attribute Description
gender undefined, male or female. This field is used for form of address, for courtesy
image_url URL of your avatar. We have another undocumented endpoint to upload an avatar.
dialcode dial code of his/her phone
phone phone of your user
is_phone_validated It indicates if this user has the phone validated
is_email_validated It indicates if this user has the email validated
vote Can the user vote when a service is finished?
allow_taxi_request_personal The user can request a service with private value equal to true (See Create service endpoint)
allow_taxi_request_company The user can request a service with private value equal to false (See Create service endpoint)
has_personal_credit_card_valid The user has a personal credit card valid
has_employee_credit_card_valid The user has a enterprise credit card valid
cost_cancellation_required_personal_stripe_enabled Undocumented field
cost_cancellation_enabled Undocumented field
can_test_request Undocumented field
required_personal_credit_card Undocumented field
allow_fixed_rate Undocumented field
default_way_to_pay Undocumented field
co2_not_emitted Undocumented field
saved_money Undocumented field
can_impersonate Undocumented field
employee Undocumented field

8.1.4 Success code

Status Code Meaning
200 OK

8.2 Edit profile

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER" \
  -X PUT \
  -d '{
      "user": {
        "first_name":"Test",
        "last_name": "Foo"
      },
      "phone": "+34123456780",
      "gender": "male"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

json_data = {
    'user': {
        'first_name': 'Test',
        'last_name': 'Foo',
    },
    'phone': '+34123456780',
    'gender': 'male',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/',
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n      \"user\": {\n        \"first_name\":\"Test\",\n        \"last_name\": \"Foo\"\n      },\n      \"phone\": \"+34123456780\",\n      \"gender\": \"male\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:


{
  "user": {
    "first_name":"Test",
    "last_name": "Foo"
  },
  "phone": "+34123456780",
  "gender": "male"
}

8.2.1 HTTP Request

PUT https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/profile/

This endpoint updates several attributes of the passenger profile. If you want to use only a generic user you should do not use this endpoint

8.2.2 Success code

Status Code Meaning
200 OK

9. Zone

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/zone/?position=-3.69073,40.40693" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json"

import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
}

params = (
    ('position', '-3.69073,40.40693'),
)

response = requests.get(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/zone/',
  headers=headers, params=params)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/zone/?position=-3.69073,40.40693");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

{
  "id": 240,
  "name": "ATOCHA",
  "immediates": true,
  "reservations": true,
  "destination_required": true,
  "min_time_request_reservation": "00:15:00",
  "min_time_request_reservation_six_seats": "00:15:00",
  "min_time_request_reservation_eco": "00:15:00",
  "min_time_request_reservation_electric_car": "00:15:00",
  "min_time_request_reservation_high_end": "00:15:00",
  "min_time_request_reservation_screen": "00:15:00",
  "min_time_request_reservation_adapted": "00:15:00",
  "min_time_request_reservation_integrated_taxi": "00:15:00",
  "min_time_request_reservation_integrated_vtc": "00:15:00",
  "min_time_request_reservation_integrated_moto": "00:15:00",
  "allow_comments": true,
  "only_credit_service": true,
  "test_zone": false,
  "need_place_info": "railstation",
  "taxis": [],
  "has_cost_cancellation_inmmediates_enabled": false,
  "has_cost_cancellation_reservations_enabled": false,
  "company_taxi_types": [
    "conventional"
  ],
  "personal_taxi_types": [
    "conventional"
  ],
  "message": "",
  "time_zone": "Europe/Madrid",
  "enabled_rate_type": false,
  "only_credit_service_fixed_rate": true,
  "delegate_always": false,
}

9.1 HTTP Request

POST https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/zone/?position=-3.69073,40.40693

This endpoint returns the configuration of a zone.

9.2 Query Parameters

Parameter Description Required
position Point (longitude,latitude) that you want to know the configuration True

9.3 Zone attributes response

Attribute Description
id The ID of the zone
name Name of the zone
immediates This field indicates if in this zone is enabled immediates services
reservations This field indicates if in this zone is enabled bookings. Immediates & reservations fields can be false (it would be a disabled zone for any reason). But reservations can not be false if immediates are true
destination_required This indicates if you need to set a destination or not when you are requesting a service
min_time_request_reservation Min. time to request a booking for conventional taxis
min_time_request_reservation_six_seats Min. time to request a booking for six seats taxis
min_time_request_reservation_eco Min. time to request a booking for eco taxis
min_time_request_reservation_electric_car Min. time to request a booking for electric taxis
min_time_request_reservation_high_end Min. time to request a booking for high-end taxis
min_time_request_reservation_screen Min. time to request a booking for screen taxis
min_time_request_reservation_adapted Min. time to request a booking for adapted taxis
min_time_request_reservation_integrated_taxi Undocumented field
min_time_request_reservation_integrated_vtc Undocumented field
min_time_request_reservation_integrated_moto Undocumented field
allow_comments the user can add comments like: "I am in front of the bank" when requests a service
only_credit_service This zone is only for credit services.
test_zone A user can request a service, but we are opening this zone and there may be an issue.
need_place_info If this value is airport, when you request must fill flight_number & flight_origin fields, these are mandatory. If the value is railstation when you request can fill train_number or train_origin. These are not required.
taxis A list of the 50 taxis closest to position param
has_cost_cancellation_inmmediates_enabled is there cost cancellation for immediate services?
has_cost_cancellation_reservations_enabled is there cost cancellation for bookings?
company_taxi_types Taxi types available for create services with private equal to False
personal_taxi_types Taxi types available for create services with private equal to True
message It is used to communicate any problem to the passenger. E.g.: A demostration
time_zone Europe / Madrid, Europe / Paris, Europe / Lisbon, Atlantic/Canary, etc
enabled_rate_type Undocumented field
only_credit_service_fixed_rate Undocumented field
delegate_always Undocumented field

9.4 Status code

Status Code Meaning
200 OK
400 Bad Request -- Point (position) out of zone (Users cannot request a Joinup in this point)

10. Service

10.1 Create Service

This endpoint creates a new service, immediate or booking.

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER" \
  -X POST \
  -d '{
    "private": false,
    "reservation": false,
    "pickup_address": "Paseo del Prado, 26 Madrid España",
    "pickup": [-3.693407, 40.4121412],
    "pickup_place_id": null,
    "destination_address": "Calle de Fernando el Católico, 42 Madrid España",
    "destination": [-3.7121572, 40.4343557],
    "destination_place_id": null,
    "comment": "",
    "rate_data": {
      "taxi_type": "eco"
    },
    "flight_number": "",
    "flight_origin": "",
    "train_number": "",
    "train_origin": "",
    "coupon": null,
    "platform_model": ""
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

json_data = {
    'private': False,
    'reservation': False,
    'pickup_address': 'Paseo del Prado, 26 Madrid Espa\xF1a',
    'pickup': [
        -3.693407,
        40.4121412,
    ],
    'pickup_place_id': None,
    'destination_address': 'Calle de Fernando el Cat\xF3lico, 42 Madrid Espa\xF1a',
    'destination': [
        -3.7121572,
        40.4343557,
    ],
    'destination_place_id': None,
    'comment': '',
    'rate_data': {
      'taxi_type': 'eco'
    },
    'flight_number': '',
    'flight_origin': '',
    'train_number': '',
    'train_origin': '',
    'coupon': None,
    'platform_model': '',
}

response = requests.post(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/', 
  headers=headers, json=json_data)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n    \"private\": false,\n    \"reservation\": false,\n    \"pickup_address\": \"Paseo del Prado, 26 Madrid Espa\xF1a\",\n    \"pickup\": [-3.693407, 40.4121412],\n    \"pickup_place_id\": null,\n    \"destination_address\": \"Calle de Fernando el Cat\xF3lico, 42 Madrid Espa\xF1a\",\n    \"destination\": [-3.7121572, 40.4343557],\n    \"destination_place_id\": null,\n    \"comment\": \"\",\n    \"rate_data\": {\n      \"taxi_type\": \"eco\"\n    },\n    \"flight_number\": \"\",\n    \"flight_origin\": \"\",\n    \"train_number\": \"\",\n    \"train_origin\": \"\",\n    \"coupon\": null,\n    \"platform_model\": \"\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

In addition to these fields there are undocumented employee/company fields

The above command returns JSON structured like this:

{
    "pk": 440214,
    "is_company_travel": true,
    "amount_str": null,
    "amount_with_coupon": null,
    "amount_cancellation": null,
    "amount_currency": "EUR",
    "passenger_extra_message": "",
    "comment": "",
    "way_to_pay": "",
    "coupon": null,
    "cost_center": "",
    "service_reason": "",
    "deferred": null,
    "deferred_pk": null,
    "extra_text_1": "",
    "extra_text_2": "",
    "extra_text_3": "",  
    "service": {
        "pk": 439930,
        "taxi": null,
        "state": 2,
        "pickup_location": [
        -3.693407,
        40.4121412
        ],
        "pickup_date": "2022-01-31T11:24:11.169761Z",
        "pickup_address": "Paseo del Prado, 26 Madrid España",
        "pickup_place_type": "",
        "updated_position": "",
        "destination_location": [
        -3.7121572,
        40.4343557
        ],
        "destination_address": "Calle de Fernando el Católico, 42 Madrid España",
        "taxi_pickup_date": null,
        "finish_date": null,
        "vehicle_type": "taxi",
        "rate_type": "",
        "rate_data": null
    }
}

10.1.1 HTTP Request

POST "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/

10.1.2 Service data request

Attribute Description Required
private True: personal services (passenger pays the service). False: company services (company pays the service) False (Default is False)
reservation True: booking. False: immediate service True
pickup_date Pickup date. Only for bookings False
pickup_address Pickup address True
pickup Pickup point. Format: [longitude, latitude] True
pickup_place_id If user is requesting in an airport or railstation you can add its id in this field for efficiency. See Place endpoint False
destination_address Destination address False (depends on destination_required field of zone)
destination Destination point. Format: [longitude, latitude] False (depends on destination_required field of zone)
destination_place_id If user is requesting in an airport or railstation like destination you can add its id in this field for efficiency. See Place endpoint False
comment Add another info False
rate_data.taxi_type Rate data is an object with a lot of info. But for this documentation we only use taxi type. This field will indicate the taxi type (See Available taxi types in Configuration provider) False (Default is convencional)
flight_number Flight info False (depends on need_place_info field of zone)
flight_origin Flight info False (depends on need_place_info field of zone)
train_number Train info False
train_origin Train info False
coupon We have a coupon system. And the user can request a service with a discount coupon False
platform_model Add any identity of your provider and version. e.g.: PROVIDER_ID@1.0.0 False
way_to_pay If private is false. You can indicates: cash, credit-card or app False

10.1.3 Service attributes response (traveller)

Attribute Description
pk Traveller id
is_company_travel It is the same like not private. False: personal services (passenger pays the service). True: company services (company pays the service)
amount_str Amount in string format
amount_with_coupon Amount with the coupon applied
amount_cancellation Cancellation amount. When a service is created always is null
amount_currency Currency. E.g.: EUR
passenger_extra_message Promotional text for some services
comment Documented in 10.1.2 Service data request section
way_to_pay Documented in 10.1.2 Service data request section
coupon Documented in 10.1.2 Service data request section
cost_center Undocumented field
service_reason Undocumented field
deferred Undocumented field
deferred_pk Undocumented field
extra_text_1 Undocumented field
extra_text_2 Undocumented field
extra_text_3 Undocumented field

10.1.4 Service attributes response (service)

Attribute Description
pk Service id
taxi Data of taxi. When a service is created always is null
state Service status
pickup_location Documented in 10.1.2 Service data request section (pickup)
pickup_date Documented in 10.1.2 Service data request section
pickup_address Documented in 10.1.2 Service data request section
pickup_place_type It indicates if you are requesting in a railstation or an airport
updated_position When you request in a railstation or in an airport without to get the coordinates from place endpoint our backend will update the pickup point to the meeting point of the railstation or the airport
destination_location Documented in 10.1.2 Service data request section (destination)
destination_address Documented in 10.1.2 Service data request section
taxi_pickup_date Date of taxi when it arrives at pickup point. When a service is created always is null
finish_date Date of taxi when it arrives at destination point. When a service is created always is null
vehicle_type Undocumented field
rate_type Undocumented field
rate_data Undocumented field

10.1.5 Status code

Status Code Meaning
201 Created
400 Bad Request -- Any validation error. E.g.: Address out of zone (Users cannot request a Joinup in this address), in this zone only can requests bookings and you are requesting an immediate service, if you request a booking with less time than zone says in the field min_time_request_reservation_*

10.2 Edit

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/440217/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER" \
  -X PUT \
  -d '{
    "private": false,
    "reservation": true,
    "pickup_date": "2022-02-02T10:15:00.000Z",
    "pickup_address": "Paseo del Prado, 26 Madrid España",
    "pickup": [-3.693407, 40.4121412],
    "pickup_place_id": null,
    "destination_address": "Calle de Fernando el Católico, 42 Madrid España",
    "destination": [-3.7121572, 40.4343557],
    "destination_place_id": null,
    "comment": "",
    "rate_data": {
      "taxi_type": "electric"
    },
    "flight_number": "",
    "flight_origin": "",
    "train_number": "",
    "train_origin": "",
    "coupon": null,
    "platform_model": ""
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

json_data = {
    'private': False,
    'reservation': True,
    'pickup_date': '2022-02-02T10:15:00.000Z',
    'pickup_address': 'Paseo del Prado, 26 Madrid Espa\xF1a',
    'pickup': [
        -3.693407,
        40.4121412,
    ],
    'pickup_place_id': None,
    'destination_address': 'Calle de Fernando el Cat\xF3lico, 42 Madrid Espa\xF1a',
    'destination': [
        -3.7121572,
        40.4343557,
    ],
    'destination_place_id': None,
    'comment': '',
    'rate_data': {
      'taxi_type': 'electric'
     },
    'flight_number': '',
    'flight_origin': '',
    'train_number': '',
    'train_origin': '',
    'coupon': None,
    'platform_model': '',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/440217/', 
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/440217/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n    \"private\": false,\n    \"reservation\": true,\n    \"pickup_date\": \"2022-02-02T10:15:00.000Z\",\n    \"pickup_address\": \"Paseo del Prado, 26 Madrid Espa\xF1a\",\n    \"pickup\": [-3.693407, 40.4121412],\n    \"pickup_place_id\": null,\n    \"destination_address\": \"Calle de Fernando el Cat\xF3lico, 42 Madrid Espa\xF1a\",\n    \"destination\": [-3.7121572, 40.4343557],\n    \"destination_place_id\": null,\n    \"comment\": \"\",\n    \"rate_data\": {\n      \"taxi_type\": \"electric\"\n    },\n    \"flight_number\": \"\",\n    \"flight_origin\": \"\",\n    \"train_number\": \"\",\n    \"train_origin\": \"\",\n    \"coupon\": null,\n    \"platform_model\": \"\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

{
  "pk": 440218,
  "amount_str": null,
  "cost_center": "",
  "service_reason": "",
  "service": {
    "pk": 439934,
    "taxi": null,
    "state": 0,
    "pickup_location": [
      -3.693407,
      40.4121412
    ],
    "pickup_date": "2022-02-02T10:15:00Z",
    "pickup_address": "Paseo del Prado, 26 Madrid España",
    "pickup_place_type": "",
    "updated_position": "",
    "destination_location": [
      -3.7121572,
      40.4343557
    ],
    "destination_address": "Calle de Fernando el Católico, 42 Madrid España",
    "taxi_pickup_date": null,
    "finish_date": null,
    "vehicle_type": "taxi",
    "rate_type": "",
    "rate_data": null
  },
  "is_company_travel": true,
  "deferred": null,
  "deferred_pk": null,
  "comment": "",
  "extra_text_1": "",
  "extra_text_2": "",
  "extra_text_3": "",
  "way_to_pay": "",
  "coupon": null,
  "amount_with_coupon": null,
  "amount_cancellation": null,
  "amount_currency": "EUR",
  "passenger_extra_message": ""
}

10.2.1 HTTP Request

PUT "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/request/<ID>

This endpoint updates a service. Only for bookings.

10.2.2 URL Parameters

Parameter Description
ID The ID of traveller

10.2.3 Status code

Status Code Meaning
200 Ok
400 Bad Request -- Any validation error. E.g.: Address out of zone (Users cannot request a Joinup in this address), if you request a booking with less time than zone says in the field min_time_request_reservation_*, etc

10.3 Current

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/current/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

response = requests.get(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/current/', 
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/current/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like these:

1: There is not any current service

{
  "count": 0
}

2: There is any current vote service. There is 4 current service (active or pending voting)

{
  "pk": 440248,
  "amount_str": "21.75 €",
  "service": {
    "pk": 439964,
    "taxi": {
      "cached_name": "John Smith"
    },
    "pickup_date": "2022-02-02T10:47:54Z",
    "destination_address": "Calle de Fernando el Católico, 40 Madrid España"
  },
  "type": "vote",
  "count": 4
}

3: There is any current active service. There is 4 current service (active or pending voting)

{
  "pk": 440246,
  "amount_str": null,
  "is_company_travel": true,
  "comment": "",
  "way_to_pay": "",
  "coupon": null,
  "amount_with_coupon": null,
  "amount_cancellation": null,
  "amount_currency": "EUR",
  "taxi_type": "conventional",
  "service__zone__time_zone": "Europe/Madrid",
  "deferred": null,
  "deferred_pk": null,  
  "cost_center": "",
  "service_reason": "",
  "extra_text_1": "",
  "extra_text_2": "",
  "extra_text_3": "",
  "company_extra_fields": null,
  "service": {
    "pk": 439962,
    "reservation": false,
    "taxi": {
      "pk": 201234, 
      "cached_name": "Tom Jonhson",
      "coords": [
        -3.7033387,
        40.4167278
      ],
      "license": "1234",
      "plate": "1234 ABC",
      "reputation_stars": 5,
      "vehicle": "vehicle_type",
      "vehicle_type": "taxi"
    },
    "state": 3,
    "pickup_location": [
      -3.693407,
      40.4121412
    ],
    "pickup_date": "2022-02-02T10:22:02.642724Z",
    "pickup_address": "Paseo del Prado, 26 Madrid España",
    "pickup_place_type": "",
    "updated_position": "",
    "destination_location": [
      -3.7121572,
      40.4343557
    ],
    "destination_address": "Calle de Fernando el Católico, 42 Madrid España",
    "taxi_pickup_date": null,
    "finish_date": null,
    "vehicle_type": "taxi",
    "rate_type": "",
    "rate_data": null,
    "extra_info": "",
    "arrival_taxi_date": null
  },
  "type": "active",
  "count": 4
}

In addition to these fields there are undocumented employee/company fields and configurations

10.3.1 HTTP Request

This endpoint returns a current service. If you have several current services you can specify an id. A current service can be a service pending voting or an active service. An active service is a service in state: pending, ongoing, pickup and running. Also an active service is a booking in state reservation or reservation accepted but it is very close to the pickup date.

GET "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/current/

or

GET "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/current/<ID>

10.3.2 URL Parameters

Parameter Description
ID The ID of traveller

10.3.3 Service attributes response (pending vote)

Attribute Description
pk The ID of traveller
amount_str Documented in 10.1.3 Service attributes response (traveller) section
type It indicates that user can vote this service
count Number of services: book, active or pending vote

In service attribute:

Attribute Description
pk The ID of service
taxi.cached_name Complete name of the taxi driver
pickup_date Documented in 10.1.2 Service data request section
destination_address Documented in 10.1.2 Service data request section

10.3.4 Service attributes response (active service)

Attribute Description
pk The ID of traveller
amount_str Documented in 10.1.3 Service attributes response (traveller) section
is_company_travel Documented in 10.1.3 Service attributes response (traveller) section
comment Documented in 10.1.2 Service data request section
way_to_pay Documented in 10.1.2 Service data request section
coupon Documented in 10.1.2 Service data request section
amount_with_coupon Documented in 10.1.3 Service attributes response (traveller) section
amount_cancellation Documented in 10.1.3 Service attributes response (traveller) section
amount_currency Documented in 10.1.3 Service attributes response (traveller) section
taxi_type Documented in 10.1.2 Service data request section (rate_data.taxi_type)
service__zone__time_zone Time zone of current zone. E.g.: Europe / Madrid, Europe / Paris, Europe / Lisbon, Atlantic/Canary, etc
type It indicates that user has an active service
count Documented in 10.3.3 Service attributes response (pending vote) section
deferred Undocumented field
deferred_pk Undocumented field
cost_center Undocumented field
service_reason Undocumented field
extra_text_1 Undocumented field
extra_text_2 Undocumented field
extra_text_3 Undocumented field
company_extra_fields Undocumented field

In service attribute:

Attribute Description
pk The ID of service
taxi.pk The ID of taxi
taxi.cached_name Complete name of the taxi driver
taxi.coords Coordinates of the taxi in real time. Format: [longitude, latitude]
taxi.license Taxi licence
taxi.plate Taxi plate
taxi.reputation_stars Taxi reputation. A value from 0 to 5
taxi.vehicle Brand & model of taxi
taxi.vehicle_type Undocumented field
reservation Documented in 10.1.2 Service data request section
state 10.1.4 Service attributes response (service)
pickup_location Documented in 10.1.2 Service data request section (pickup)
pickup_date Documented in 10.1.2 Service data request section
pickup_address Documented in 10.1.2 Service data request section
pickup_place_type 10.1.4 Service attributes response (service)
updated_position 10.1.4 Service attributes response (service)
destination_location Documented in 10.1.2 Service data request section (destination)
destination_address Documented in 10.1.2 Service data request section
taxi_pickup_date 10.1.4 Service attributes response (service)
finish_date 10.1.4 Service attributes response (service)
extra_info A message for the passenger. E.g.: "Personalized welcome with a sign at the exit of the flight"
arrival_taxi_date In some zones, we do not know the coords of the taxi. So, we will estimate an arrival taxi date
vehicle_type Undocumented field
rate_type Undocumented field
rate_data Undocumented field

10.3.5 Status code

Status Code Meaning
200 Ok

10.4 Services

curl "https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/" \
   -H "Authorization: beep-beep-beep-beep-beep" \
   -H "Content-Type: application/json" \
   -H "Impersonate: EMAIL_PASSENGER"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

response = requests.get(
  'https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/', 
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:


{
  "count": 4,
  "next": null,
  "previous": null,
  "results": [
    {
      "pk": 440218,
      "amount_str": null,
      "is_company_travel": true,
      "comment": "",
      "way_to_pay": "",
      "coupon": null,
      "amount_with_coupon": null,
      "amount_cancellation": null,
      "amount_currency": "EUR",
      "service__zone__time_zone": "Europe/Madrid",
      "relaunched": null,
      "finished_from_cancelled_passenger": false,
      "taxi_type": "conventional",
      "company_extra_fields": null,
      "credit_card": false,
      "cost_center": "",
      "service_reason": "",
      "deferred": null,
      "deferred_pk": null,
      "extra_text_1": "",
      "extra_text_2": "",
      "extra_text_3": "",
      "service": {
        "pk": 439934,
        "taxi": null,
        "state": 7,
        "pickup_location": [
          -3.693407,
          40.4121412
        ],
        "pickup_date": "2022-02-02T10:15:00Z",
        "pickup_address": "Paseo del Prado, 26 Madrid España",
        "pickup_place_type": "",
        "updated_position": "",
        "destination_location": [
          -3.7121572,
          40.4343557
        ],
        "destination_address": "Calle de Fernando el Católico, 42 Madrid España",
        "taxi_pickup_date": null,
        "test_service": false,
        "finish_date": null,
        "flight_number": "",
        "flight_origin": "",
        "train_number": "",
        "train_origin": "",
        "relaunched": null,
        "vehicle_type": "taxi",
        "rate_type": "",
        "rate_data": null,
        "distance": 4664,
        "co2_equivalent": 0.68518824,
        "co2_emitted": 0.67660648,
        "n2o_emitted": 0.00858176,
        "ch4_emitted": 0.0000200552
      },
    },
    ...
  ]
}

In addition to these fields there are undocumented employee/company fields

10.4.1 HTTP Request

GET https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/

This endpoint returns a paginated list of services of an user. This endpoint has parameters to filter the result or order it.

10.4.2 URL Parameters

Parameter Description
service__state You can filter by Service status
service__pickup_date__lte You can filter by pickup date. Less or equal than a value in UTC
service__pickup_date__gte You can filter by pickup date. Great or equal than a value in UTC
ordering You can order by: service__state, service__pickup_date, -service__state, -service__pickup_date

10.4.3 Service attributes response (traveller)

Attribute Description
pk Traveller id
amount_str Documented in 10.1.3 Service attributes response (traveller) section
is_company_travel Documented in 10.1.3 Service attributes response (traveller) section
comment Documented in 10.1.2 Service data request section
way_to_pay Documented in 10.1.2 Service data request section
coupon Documented in 10.1.2 Service data request section
amount_with_coupon Documented in 10.1.3 Service attributes response (traveller) section
amount_cancellation Documented in 10.1.3 Service attributes response (traveller) section
amount_currency Documented in 10.1.3 Service attributes response (traveller) section
service__zone__time_zone Documented in 10.3.4 Service attributes response (active service) section
relaunched Traveller id of the new relaunched traveller
finished_from_cancelled_passenger This service was cancelled by passenger, but this service has cancellation amount, so its state is finished
taxi_type Documented in 10.1.2 Service data request section (rate_data.taxi_type)
company_extra_fields Undocumented field
credit_card Undocumented field
cost_center Undocumented field
service_reason Undocumented field
deferred Undocumented field
deferred_pk Undocumented field
extra_text_1 Undocumented field
extra_text_2 Undocumented field
extra_text_3 Undocumented field

10.4.4 Service attributes response (service)

Attribute Description
pk Service id
taxi Taxi data Documented in 10.3.4 Service attributes response (active service) section
state 10.1.4 Service attributes response (service)
pickup_location Documented in 10.1.2 Service data request section (pickup)
pickup_date Documented in 10.1.2 Service data request section
pickup_address Documented in 10.1.2 Service data request section
pickup_place_type 10.1.4 Service attributes response (service)
updated_position 10.1.4 Service attributes response (service)
destination_location Documented in 10.1.2 Service data request section
destination_address Documented in 10.1.2 Service data request section
taxi_pickup_date 10.1.4 Service attributes response (service)
finish_date 10.1.4 Service attributes response (service)
flight_number Documented in 10.1.2 Service data request section
flight_origin Documented in 10.1.2 Service data request section
train_number Documented in 10.1.2 Service data request section
train_origin Documented in 10.1.2 Service data request section
relaunched Service id of the new relaunched service
test_service Undocumented field
vehicle_type Undocumented field
rate_type Undocumented field
rate_data Undocumented field
distance distance traveled in meters
co2_equivalent CO2 equivalent = Kg CO2 emitted + a conversion of Kg N2O emitted in Kg CO2 + a conversion of Kg CH4 emitted in Kg CO2.
co2_emitted Kg CO2 emitted in the service
n2o_emitted Kg N2O emitted in the service
ch4_emitted Kg CH4 emitted in the service

10.4.5 Status code

Status Code Meaning
200 Ok

10.5 Cancel

curl "https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/cancel/<ID>/" \
   -H "Authorization: beep-beep-beep-beep-beep" \
   -H "Content-Type: application/json" \
   -H "Impersonate: EMAIL_PASSENGER" \
   -X PUT 
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/cancel/<ID>/',
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-documentacion/apps/passenger/PLATFORM/VERSION/services/cancel/<ID>/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:


{
  "cost_cancellation": false,
  "amount_cancellation": null
}

10.5.1 HTTP Request

PUT "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/cancel/<ID>/

This endpoint cancels a service.

10.5.2 URL Parameters

Parameter Description
ID The ID of traveller

10.5.3 Attributes response

Attribute Description
cost_cancellation Has this cancellation cost cancellation?
amount_cancellation How much is the cancellation cost?

10.5.4 Status code

Status Code Meaning
200 Ok
404 Not found

10.6 Vote

This endpoint allows users to vote. Depends on configuration provider

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/vote/<ID>/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Content-Type: application/json" \
  -H "Impersonate: EMAIL_PASSENGER" \
  -X PUT \
  -d '{
    "vote": "down",
    "comment": "bla bla bla"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'EMAIL_PASSENGER',
}

json_data = {
    'vote': 'down',
    'comment': 'bla bla bla',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/vote/<ID>/',
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/vote/<ID>/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "EMAIL_PASSENGER");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n    \"vote\": \"down\",\n    \"comment\": \"bla bla bla\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}
{
  "ask_app_vote": false
}

10.6.1 HTTP Request

PUT "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/services/vote/<ID>/

10.6.1 Vote data request

Attribute Description Required
vote Options: up, down, nothing True
comment Add any info about your vote, specially for down vote False

10.6.2 Vote attribute response

Attribute Description
ask_app_vote Undocumented field

10.6.3 Status code

Status Code Meaning
200 Ok
404 Not found

10.7 Service Status

Status Name Type Meaning
0 Reserved Booking Initial state in a booking
1 Reserved accepted Booking A taxi driver accepted a booking
2 Pending Immediate Initial state in a immediate service
3 Ongoing Immediate/booking Taxi is ongoing to pickup point
4 Pickup Immediate/booking Taxi is in pickup point
5 Running Immediate/booking Taxi goes to destination
6 Finished Immediate/booking The service is finished successfully
7 Cancelled passenger Immediate/booking Passenger cancelled the service
8 Cancelled taxi Immediate/booking Taxi driver cancelled the service. But our system will create another service and it will search for another taxi. (it is not a common thing)
9 Cancelled no client Immediate/booking Taxi driver cancelled the service because he/she did not find the passenger (more strange still). Our system will not create another service
10 Dismissed Immediate/booking We do not find a taxi driver or there is any error code (more strange still)
13 Cancelled relaunch Immediate/booking The service is relaunching to find a taxi driver. Our system will create another service
14 Cancelled passenger edited Immediate/booking Passenger edit the service, our system will create another service

11. Places

# Airports closer to Atocha
curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/places/?type=railstation&position=-3.681477,40.398396" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Impersonate': 'foo.bar@example.com',
}

params = (
    ('type', 'railstation'),
    ('position', '-3.681477,40.398396'),
)
# Airports closer to Atocha
response = requests.get(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/places/',
  headers=headers, params=params)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
    // Airports closer to Atocha
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/places/?type=railstation&position=-3.681477,40.398396");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

[
  {
    "id": 1,
    "name": "Aeropuerto Madrid T1",
    "address": "Aeropuerto T1 - Salidas",
    "location": {
        "type": "Point",
        "coordinates": [
            -3.5795833262939294,
            40.477378030587696
        ]
    }
  },
  {
    "id": 2,
    "name": "Aeropuerto Madrid T2",
    "address": "Aeropuerto Madrid Barajas T2 salidas",
    "location": {
        "type": "Point",
        "coordinates": [
            -3.5805006417767104,
            40.47390771493706
        ]
    }
  },
  ...
  {
    "id": 300,
    "name": "Name of airport of train station",
    "address": "Postal address of airport of train station",
    "location": {
        "type": "Point",
        "coordinates": [
            longitude,
            latitude
        ],
    }
  },

]

11.1 HTTP Request

GET https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/places/

This endpoint retrieves all places (train station and / or airports). You can filter by type, and you can order by closeness to a position

11.2 Query Parameters

Parameter Description Required Default
type railstation or airport. With this parameter filter by train station or airport False Return airports & train stations
position With this parameter we get the places ordering by closer to this position (longitude, latitude) False Return places with random ordering

11.3 Places attributes response

Parameter Description
id The ID of the place
name Name of the place
location Coordinates about this place (longitude, latitude)
address Postal address of the place

11.4 Status code

Status Code Meaning
200 OK

12. Address

12.1 Address attributes data & response

Attribute Description
id The ID of the address
name Name of the address
pickup Coordinates about this address (longitude, latitude)
address Postal address
type Type of address: home, work or general.

12.2 Get All Address

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Impersonate': 'foo.bar@example.com',
}

response = requests.get(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/',
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

[
  {
    "id": 28542,
    "name": "Joinup office",
    "pickup": [
      -3.6945,
      40.40659
    ],
    "address": "Paseo de Santa María de la Cabeza, 10, 28045 Madrid España",
    "type": "work"
  },
  {
    "id": 28543,
    "name": "My home",
    "pickup": [
      -3.70208,
      40.45036
    ],
    "address": "Calle Jaén, 10, Madrid, España",
    "type": "home"
  },
  ...
  {
    "id": 38345,
    "name": "NAME",
    "pickup": [
      LONGITUDE,
      LATITUDE
    ],
    "address": "ADDRESS",
    "type": "home|work|general"
  },

]

12.2.1 HTTP Request

GET https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/

This endpoint retrieves all address of an user.

12.2.2 Status code

Status Code Meaning
200 OK

12.3 Get an Address

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Impersonate': 'foo.bar@example.com',
}

response = requests.get(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/',
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("GET");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

{
  "id": 28542,
  "name": "Joinup office",
  "pickup": [
    -3.6945,
    40.40659
  ],
  "address": "Paseo de Santa María de la Cabeza, 10, 28045 Madrid España",
  "type": "work"
}

12.3.1 HTTP Request

This endpoint retrieves a specific address.

GET https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/<ID>

12.2.2 URL Parameters

Parameter Description
ID The ID of the address to retrieve

12.2.3 Status code

Status Code Meaning
200 OK
404 Not found -- Address does not found or this address belongs to another user

12.4 Create an Address

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/" \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Joinup office",
    "pickup": [
      -3.6945, 40.40659
    ],
    "address": "Paseo de Santa María de la Cabeza, 10, 28045 Madrid España",
    "type": "work"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Content-Type': 'application/json',
    'Impersonate': 'foo.bar@example.com',
}

json_data = {
    'name': 'Joinup office',
    'pickup': [
        -3.6945,
        40.40659,
    ],
    'address': 'Paseo de Santa Mar\xEDa de la Cabeza, 10, 28045 Madrid Espa\xF1a',
    'type': 'work',
}

response = requests.post(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/',
  headers=headers, json=json_data)

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Content-Type", "application/json");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n    \"name\": \"Joinup office\",\n    \"pickup\": [\n      -3.6945, 40.40659\n    ],\n    \"address\": \"Paseo de Santa Mar\xEDa de la Cabeza, 10, 28045 Madrid Espa\xF1a\",\n    \"type\": \"work\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

{
  "id":28542,
  "name": "Joinup office",
  "pickup": [
    -3.6945,
    40.40659
  ],
  "address": "Paseo de Santa María de la Cabeza, 10, 28045 Madrid España",
  "type": "work"
}

12.4.1 HTTP Request

POST https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/

This endpoint creates a new address.

12.4.1 Status code

Status Code Meaning
201 Created
400 Bad Request -- Address out of zone (Users cannot request a Joinup in this address), the user has already a address with the same name, etc

12.5 Edit an Address

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/" \
  -X PUT \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Joinup office (in Madrid)",
    "pickup": [
      -3.6945, 40.40659
    ], 
    "address": "Paseo de Santa María de la Cabeza, 10, 28045 Madrid España",
    "type": "work"
  }'
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Impersonate': 'foo.bar@example.com',
    'Content-Type': 'application/json',
}

json_data = {
    'name': 'Joinup office (in Madrid)',
    'pickup': [
        -3.6945,
        40.40659,
    ],
    'address': 'Paseo de Santa Mar\xEDa de la Cabeza, 10, 28045 Madrid Espa\xF1a',
    'type': 'work',
}

response = requests.put(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/',
  headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("PUT");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");
        httpConn.setRequestProperty("Content-Type", "application/json");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n    \"name\": \"Joinup office (in Madrid)\",\n    \"pickup\": [\n      -3.6945, 40.40659\n    ], \n    \"address\": \"Paseo de Santa Mar\xEDa de la Cabeza, 10, 28045 Madrid Espa\xF1a\",\n    \"type\": \"work\"\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command returns JSON structured like this:

{
  "id":28542,
  "name": "Joinup office (in Madrid)",
  "pickup": [
    -3.6945,
    40.40659
  ],
  "address": "Paseo de Santa María de la Cabeza, 10, 28045 Madrid España",
  "type": "work"
}

12.5.1 HTTP Request

PUT https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/<ID>

12.5.2 URL Parameters

Parameter Description
ID The ID of the address to retrieve

This endpoint edit a current address of an user.

12.5.2 Status code

Status Code Meaning
200 Ok
400 Bad Request -- Address out of zone (Users cannot request a Joinup in this address), the user has already a address with the same name, etc
404 Not found -- Address does not found or this address belongs to another user

12.6 Delete an address

curl "https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/" \
  -X DELETE \
  -H "Authorization: beep-beep-beep-beep-beep" \
  -H "Impersonate: foo.bar@example.com"
import requests

headers = {
    'Authorization': 'beep-beep-beep-beep-beep',
    'Impersonate': 'foo.bar@example.com',
}

response = requests.delete(
  'https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/',
  headers=headers)
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/28542/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("DELETE");

        httpConn.setRequestProperty("Authorization", "beep-beep-beep-beep-beep");
        httpConn.setRequestProperty("Impersonate", "foo.bar@example.com");

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

The above command does not return anything (status code 204 No Content).

12.6.1 HTTP Request

This endpoint deletes a specific address.

DELETE https://api.joinupbackend/api/corporative-PROVIDER-SLUG/apps/passenger/PLATFORM/VERSION/address/<ID>

12.6.2 URL Parameters

Parameter Description
ID The ID of the address to delete

12.6.3 Status code

Status Code Meaning
204 No Content
404 Not found -- Address does not found or this address belongs to another user

13. Push notifications

It is the only part of the provider integration ad-hoc. But it could be an example

curl "https://api.provider/api/ANY-PATH/" \
  -H "Authorization: auu-auu-auu-auu-auu" \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{
      "traveller_id": 1234,
      "event": 2
  }'
import requests

headers = {
    'Authorization': 'auu-auu-auu-auu-auu',
    'Content-Type': 'application/json',
}

json_data = {
    'traveller_id': 1234,
    'event': 2,
}

response = requests.post(
    'https://api.provider/api/ANY-PATH/',
    headers=headers, json=json_data)
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Scanner;

class Main {

    public static void main(String[] args) throws IOException {
        URL url = new URL("https://api.provider/api/ANY-PATH/");
        HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
        httpConn.setRequestMethod("POST");

        httpConn.setRequestProperty("Authorization", "auu-auu-auu-auu-auu");
        httpConn.setRequestProperty("Content-Type", "application/json");

        httpConn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(httpConn.getOutputStream());
        writer.write("{\n      \"traveller_id\": 1234,\n      \"event\": 2\n  }");
        writer.flush();
        writer.close();
        httpConn.getOutputStream().close();

        InputStream responseStream = httpConn.getResponseCode() / 100 == 2
                ? httpConn.getInputStream()
                : httpConn.getErrorStream();
        Scanner s = new Scanner(responseStream).useDelimiter("\\A");
        String response = s.hasNext() ? s.next() : "";
        System.out.println(response);
    }
}

To track services in real time, our system can make requests to your system when there is an important event (e.g.: status change). It is possible you do not need it, but it is very recommended if you want to track services.

Our recommendation is to use push notifications and polling system. So you know the data service every 30 seconds / 1 minute and if there is any important event immediately.

In addition to status changes, we can inform about next events

Event Final time Type Meaning
20 Service final time Immediate We are still looking a taxi for you
22 Service modified Immediate/booking Service info has been modified

14. Success codes

The Joinup API uses the following status codes:

Status Code Meaning
200 OK -- The request was OK
201 Created -- The request was complete, and a new resource was created
204 No Content -- A status code and a header are given in the response, but there is no entity-body in the reply

15. Errors

The Joinup API uses the following error status codes:

Status Code Meaning
400 Bad Request -- Your request is invalid. Your request does not pass some validation
401 Unauthorized -- Your auth header is wrong or it was not provided
403 Forbidden -- User in impersonate header can not do this action
404 Not Found -- The resource does not exists or the resource belongs to another user
405 Method Not Allowed -- You tried to access our API with an invalid method
500 Internal Server Error -- We had a problem with our server. Try again later
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later