curl --request POST \
--url https://api.withterminal.com/tsp/v1/public-token/exchange \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"publicToken": "pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG"
}
'import requests
url = "https://api.withterminal.com/tsp/v1/public-token/exchange"
payload = { "publicToken": "pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({publicToken: 'pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG'})
};
fetch('https://api.withterminal.com/tsp/v1/public-token/exchange', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.withterminal.com/tsp/v1/public-token/exchange",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'publicToken' => 'pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.withterminal.com/tsp/v1/public-token/exchange"
payload := strings.NewReader("{\n \"publicToken\": \"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.withterminal.com/tsp/v1/public-token/exchange")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"publicToken\": \"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.withterminal.com/tsp/v1/public-token/exchange")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"publicToken\": \"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG\"\n}"
response = http.request(request)
puts response.read_body{
"id": "conn_01GV12VR4DJP70GD1ZBK0SDWFH",
"company": {
"name": "Frank's Trucking",
"dotNumbers": [
"1234567"
]
},
"account": {
"name": "Frank's Trucking",
"dotNumbers": [
"1234567"
],
"user": {
"sourceId": "1234567",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}
},
"provider": {
"code": "geotab",
"name": "Geotab"
},
"syncMode": "automatic",
"token": "con_tkn_22vUhkC6tgre4kwaYfUkCDA1rzn6eyb4",
"createdAt": "2021-01-06T03:24:53.000Z",
"updatedAt": "2021-01-06T03:24:53.000Z",
"status": "connected",
"options": {
"ingestHistoryFromSourceSystem": true
},
"linkUrl": "https://link.withterminal.com/connection/{CONNECTION_ID}?key={PUBLISHABLE_KEY}",
"externalId": "1234",
"sourceId": "123456789",
"tags": [
"Tag Name"
],
"filters": {
"vehicles": {
"status": "active",
"excludeIds": [
"vcl_01D8ZQFGHVJ858NBF2Q7DV9MNC"
],
"includeIds": [
"vcl_01D8ZQFGHVJ858NBF2Q7DV9MNC"
]
},
"drivers": {
"status": "active",
"excludeIds": [
"drv_01D8ZQFGHVJ858NBF2Q7DV9MNC"
],
"includeIds": [
"drv_01D8ZQFGHVJ858NBF2Q7DV9MNC"
]
}
}
}{
"code": "bad_request",
"message": "Invalid request body",
"detail": [
{
"message": "'vehicleId' property must be a valid ulid",
"path": "{requestQuery}.vehicleId",
"suggestion": "Please ensure you submit a valid 'vehicleId' property",
"context": {}
}
]
}{
"code": "unauthorized",
"message": "Unauthorized Request",
"detail": "Please ensure you have a valid API key"
}{
"code": "forbidden",
"message": "Forbidden Request",
"detail": "Please ensure the connection token matches the resource you are attempting to access."
}{
"code": "not_found",
"message": "Resource not found",
"detail": "Could not find resource with ID: 2342342"
}{
"code": "too_many_requests",
"message": "Too Many Requests",
"retryAfter": 60,
"detail": "You have exceeded your rate limit. Please try again later."
}{
"code": "internal_server_error",
"message": "Internal Server Error",
"detail": "Something went wrong"
}{
"code": "gateway_timeout",
"message": "Gateway Timeout"
}Public Token Exchange
Exchange the publicToken returned by our hosted authentication flow for a long lived connection token that will be used when requesting data from a customer’s TSP.
curl --request POST \
--url https://api.withterminal.com/tsp/v1/public-token/exchange \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"publicToken": "pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG"
}
'import requests
url = "https://api.withterminal.com/tsp/v1/public-token/exchange"
payload = { "publicToken": "pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({publicToken: 'pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG'})
};
fetch('https://api.withterminal.com/tsp/v1/public-token/exchange', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.withterminal.com/tsp/v1/public-token/exchange",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'publicToken' => 'pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.withterminal.com/tsp/v1/public-token/exchange"
payload := strings.NewReader("{\n \"publicToken\": \"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.withterminal.com/tsp/v1/public-token/exchange")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"publicToken\": \"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.withterminal.com/tsp/v1/public-token/exchange")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"publicToken\": \"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG\"\n}"
response = http.request(request)
puts response.read_body{
"id": "conn_01GV12VR4DJP70GD1ZBK0SDWFH",
"company": {
"name": "Frank's Trucking",
"dotNumbers": [
"1234567"
]
},
"account": {
"name": "Frank's Trucking",
"dotNumbers": [
"1234567"
],
"user": {
"sourceId": "1234567",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com"
}
},
"provider": {
"code": "geotab",
"name": "Geotab"
},
"syncMode": "automatic",
"token": "con_tkn_22vUhkC6tgre4kwaYfUkCDA1rzn6eyb4",
"createdAt": "2021-01-06T03:24:53.000Z",
"updatedAt": "2021-01-06T03:24:53.000Z",
"status": "connected",
"options": {
"ingestHistoryFromSourceSystem": true
},
"linkUrl": "https://link.withterminal.com/connection/{CONNECTION_ID}?key={PUBLISHABLE_KEY}",
"externalId": "1234",
"sourceId": "123456789",
"tags": [
"Tag Name"
],
"filters": {
"vehicles": {
"status": "active",
"excludeIds": [
"vcl_01D8ZQFGHVJ858NBF2Q7DV9MNC"
],
"includeIds": [
"vcl_01D8ZQFGHVJ858NBF2Q7DV9MNC"
]
},
"drivers": {
"status": "active",
"excludeIds": [
"drv_01D8ZQFGHVJ858NBF2Q7DV9MNC"
],
"includeIds": [
"drv_01D8ZQFGHVJ858NBF2Q7DV9MNC"
]
}
}
}{
"code": "bad_request",
"message": "Invalid request body",
"detail": [
{
"message": "'vehicleId' property must be a valid ulid",
"path": "{requestQuery}.vehicleId",
"suggestion": "Please ensure you submit a valid 'vehicleId' property",
"context": {}
}
]
}{
"code": "unauthorized",
"message": "Unauthorized Request",
"detail": "Please ensure you have a valid API key"
}{
"code": "forbidden",
"message": "Forbidden Request",
"detail": "Please ensure the connection token matches the resource you are attempting to access."
}{
"code": "not_found",
"message": "Resource not found",
"detail": "Could not find resource with ID: 2342342"
}{
"code": "too_many_requests",
"message": "Too Many Requests",
"retryAfter": 60,
"detail": "You have exceeded your rate limit. Please try again later."
}{
"code": "internal_server_error",
"message": "Internal Server Error",
"detail": "Something went wrong"
}{
"code": "gateway_timeout",
"message": "Gateway Timeout"
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Token returned by the authentication flow. Public tokens are one time use and expire after they are exchanged for a long-lived connection token.
^pub_tkn_\S+$"pub_tkn_9jNzH26e5b9RgErDnRt8zfm5emDUUyyG"
Response
OK
The connection your application has with your customer's TSP.
"conn_01GV12VR4DJP70GD1ZBK0SDWFH"
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Enum values:
automatic: Terminal will keep this connections data up to datemanual: Terminal will only sync data upon request
automatic, manual This token is used when interacting with a connections' data.
^con_tkn_\S+$"con_tkn_22vUhkC6tgre4kwaYfUkCDA1rzn6eyb4"
The current status of the connection.
connected, disconnected, archived, pending_deletion - Omnitracs Options
- Omnitracs ES Options
- Omnitracs XRS Options
Show child attributes
Show child attributes
The URL to send your user to in order to have them re-authenticate the connection.
"https://link.withterminal.com/connection/{CONNECTION_ID}?key={PUBLISHABLE_KEY}"
An optional ID from your system that can be used to reference connections.
"1234"
The ID used in the source system to represent the account this connection has or had access to.
This may be an organizationId or accountId.
Note: not all systems expose this information, in which case it may be undefined.
"123456789"
An optional list of tags from your system that can be used to reference connections.
Filters applied to connection data
Show child attributes
Show child attributes