Overview
The Leads Integration Platform allows Strategic Partners to easily integrate with ServiceTitan and pass bookings into a specific account in ServiceTitan.
After the ServiceTitan admin sets up the end-to-end configuration of a Strategic Partner through the ServiceTitan Admin Portal, the integration is enabled for ServiceTitan tenants to configure and get the bookings made through the Strategic Partner's platform into their ServiceTitan account.
Who uses this feature
Administrators, Customer Service Representatives (CSRs), Marketing Managers, Operations Managers, and Project Managers.
Feature configuration
Account configuration is required to use this feature. Please contact Technical Support for details.
API
For the Leads Integration Platform, we support two environments: Sandbox and Production. Client credentials for each environment will be provided respectively (please contact your Partner Manager at ServiceTitan to get the credentials).
Endpoints
Token generation
URL | Sandbox URL: https://marketing-integrations-identity-demo.st.dev Prod URL: https://leads-identity.servicetitan.com |
Format | application/x-www-form-urlencoded |
Account Pairing and Booking
URL | Sandbox URL: https://leads-booking-api-demo.st.dev |
Format | application/json |
Methods
The accepted method for integration setup, account pairing, and booking is described in the following table.
POST | |
|---|---|
/connect/token | Generate token |
/api/integrations/accounts | Set the account pairing status to PROCESSING or DECLINED |
/api/integrations/accounts | Send account/profiles information, set account pairing status to COMPLETED |
/api/integrations/bookings | Send a booking request to ServiceTitan |
Models
Token
There is no specific format defined for the components below.
Name | Data Type | Mandatory | Notes |
|---|---|---|---|
client_id | string | Yes | Please contact your Partner Manager at ServiceTitan to get the credentials |
client_secret | string | Yes | Please contact your Partner Manager at ServiceTitan to get the credentials |
grant_type | string | Yes | "client_credentials" |
Account Pairing
When pairing accounts we recommend the partners to follow these steps:
When the account pairing hasn't taken place yet, send the status PROCESSING or DECLINED to ServiceTitan to showcase the real-time status of the pairing.
After the pairing takes place, send account or profile information to ServiceTitan along with the COMPLETED status.
Name | Data Type | Mandatory | Notes |
|---|---|---|---|
requestId | string | Yes | Should include up to 128 symbols, no special characters |
status | string | Yes | Possible values are "COMPLETED", "PROCESSING", and "DECLINED" |
account.id | string | Yes | Supports up to 128 symbols, no special characters |
account.name | string | Yes | Supports up to 128 symbols |
account.profiles.id | string | Yes | Supports up to 128 symbols |
account.profiles.name | string | Yes | Supports up to 128 symbols |
Booking
Name | Data Type | Mandatory | Notes |
|---|---|---|---|
idempotencyToken | string | Yes | Must be unique, with no spaces |
partnerBookingId | string | Yes | Must be unique, with no spaces |
slot.accountId | string | Yes | No spaces. Supports up to 128 symbols |
slot.profileId | string | Yes | No spaces |
slot.serviceId | string | Yes | No spaces |
slot.startSec | integer | No | The Unix timestamp for the booking's arrival window start |
slot.durationSec | integer | No | Booking's arrival window duration in seconds |
address.streetAddress | string | Yes | N/A |
description | string | No | N/A |
extraDetails | string | No | Integration-specific data about incoming bookings. JSON Array of string-to-string mappings |
externalBookingUrl | string | No | N/A |
Errors
ServiceTitan uses HTTP response codes to indicate the success or failure of an API request. In general, for successful cases, HTTP 200 status will be returned. Codes in the 4xx range indicate an error that failed given the information provided (For example, a required parameter was omitted, a duplicate parameter request was sent, and more). Codes in the 5xx range indicate an error with ServiceTitan 's servers (these are rare cases).
Some 4xx errors that could be handled programmatically include an error code, trace id, and human-readable message that briefly explains the error reported. The error JSON response looks like this:
{
"code": 10001,
"message": "One or more validation errors occurred",
"status": 400,
"stTraceId": "0f8fad5b-d9cb-469f-a165-70867728950e",
"errors": [
"partnerBookingId must be specified",
"idempotencyToken must be specified"
]
}code
An error code. Common values that could be handled programmatically are listed below.
message
A human-readable message providing more details about the error.
status
The HTTP status code generated by the origin server for this occurrence of the error.
stTraceId
Internal support identifier. When reporting a bug related to an API call, include the stTraceId to help us find log data for debugging.
errors
Optional. For cases when multiple errors occur, a human-readable message for each one is included in this list.
Error Codes
Code | Name | Description |
|---|---|---|
11102 | IntegrationDisabled | Integration is disabled for the provided slot.accountId account. |
11302 | DuplicateBooking | A booking with a specified partnerBookingId already exists. |
11303 | DuplicateIdempotencyToken | The token provided in idempotencyToken has already been used. You must create a new token before you retry this request. |
11304 | DuplicateExtraDetail | The key/value pairs provided with extraDetails contain case-insensitive duplicates. |
15102 | InvalidAccountStatusChange | Account status change from the current state to provided status value is not valid. |
15103 | InvalidAccountData | The account is not provided or its data is not valid. |
15202 | RequestIdNotFound | An account with a specified requestId does not exist. |
15203 | AccountNotFound | An account with a specified slot.accountId does not exist. |
15204 | ProfileNotFound | A profile with a specified slot.profileId does not exist. |
15302 | DuplicateRequestId | An account with a provided requestId was already created. |
15303 | DuplicateAccount | An account with a provided account.id already exists. |
15304 | DuplicateProfile | A profile with a provided account.profiles.id already exists. |
For more about the Error JSON scheme, see here.
Server-to-server authentication
To send requests to ServiceTitan endpoints, the client should pass authentication through the OAuth Client Credentials Flow. ServiceTitan will provide the client_id, client_secret, and grant_type data for which the Strategic Partner should authenticate. The process is described in the following diagram:

The Partner gets Authenticated in ServiceTitan Auth Server and in response gets an access token. Using this access token the Partner makes calls to ServiceTitan endpoints.
Note: Generated Access Token's lifetime is one hour. After the Generated Access Token expires you need to pass the same above mentioned flow to get access again.
URL: https://leads-identity-demo.st.dev/connect/token
Method: POST
Content-Type: application/x-www-form-urlencoded
Body:
[
{key: 'client_id', value: ask from Service Titan},
{key: 'client_secret', value: ask from Service Titan},
{key: 'grant_type', value: ask from Service Titan},
]Webhooks
Webhooks allow real-time updates to the Partner through HTTP requests.
Interface
First, a Lead webhooks to Partner will be implemented. Once you implement the lead webhooks an event streaming system (Kafka, Azure Event Bus) can be added as an option.
Setup
Webhooks setup is required on the Partner's side and in ServiceTitan.
Partner side
Partner should:
Configure a publicly accessible endpoint(s) with {st-prefix} to which ServiceTitan can send HTTP requests.
ServiceTitan side
To configure Webhooks for the Partner, Partner should:
Provide an {st-prefix} URL prefix (For example, https://api.partner.com/servicetitan/webhooks)
Optionally, you can provide a {secret-from-partner} input as a value in 'Webhook Message Signing Key'
Configure webhooks supported by the partner (Accounts, Profiles, or Availability).
Based on that, ServiceTitan generates the URL (for example, https://api.partner.com/servicetitan/webhooks/services) for each enabled webhook, and sends the updates to the Partner. If {secret-from-partner} is provided, it will be included in the X-STLeads-Token header, which helps to validate if ServiceTitan sent the request. 'X-STLeads-Token' is the default header name. You can provide another name for the header.
Webhooks requests
POST: {st-prefix}/accounts (For example, https://api.partner.com/servicetitan/webhooks/accounts)
POST: {st-prefix}/profiles (For example, https://api.partner.com/servicetitan/webhooks/profiles)
POST: {st-prefix}/services (For example, https://api.partner.com/servicetitan/webhooks/services)
NOTE: Services webhook is not available yet
POST: {st-prefix}/availabilities (For example, https://api.partner.com/servicetitan/webhooks/availabilities)
The list of the available webhooks is currently on Production: Accounts.
Note: HTTP failures retry mechanism will be supported in the later stages.
Automated Lead Status Updates
Automated Lead Status Updates' webhooks enable ServiceTitan to automatically and progressively send information about leads performance directly to partners.
This helps partners gain a clear understanding of the performance of the leads generated from their service.
For all types of lead status updates, we send the following information to partners.
Name | Data Type | Notes |
|---|---|---|
partnerBookingId | string | Booking ID that we received from a partner at the booking creation request |
accountId | string | Account ID that we received from a partner at the booking creation request |
profileId | string | Profile ID that we received from a partner at the booking creation request |
statusUpdateId | string | Unique ID for each status update request |
status | string | Status update event type |
timestamp | integer | A timestamp of an occurred event (Unix epoch format) |
eventData | object | Additional data of occurred event |
The following is detailed information about each event type:
Booking accepted event
This event occurs when the booking sent from the partner is accepted on the ST side.
POST: {st-prefix}/leads/accepted (For example, https://api.partner.com/servicetitan/webhooks/leads/accepted)
Name | Data Type | Notes |
acceptedTimestamp | integer | A timestamp when the booking is accepted on the ST side |
leadDeliveredTimestamp | integer | A timestamp when the booking is received from a partner on the initial booking creation request |
{
"partnerBookingId": "someBookingId",
"accountId": "someAccountId",
"profileId": "someProfileId",
"statusUpdateId": "uniqueValuePerRequest"
"status": "Accepted",
"timestamp": 1658313865,
"eventData": {
"acceptedTimestamp": 1658313864,
"leadDeliveredTimestamp": 1658312877
}
}Booking declined event
This event occurs when the booking sent from the partner is declined on the ST side.
POST: {st-prefix}/leads/declined (For example, https://api.partner.com/servicetitan/webhooks/leads/declined)
Name | Data Type | Notes |
|---|---|---|
declineTimestamp | integer | A timestamp when the booking is declined on the ST side |
declineReason | string | The reason why the booking is declined |
leadDeliveredTimestamp | integer | A timestamp when the booking is received from a partner on the initial booking creation request |
{
"partnerBookingId": "someBookingId",
"accountId": "someAccountId",
"profileId": "someProfileId",
"statusUpdateId": "uniqueValuePerRequest",
"status": "Declined",
"timestamp": 1658313105,
"eventData": {
"declineTimestamp": 1658313104,
"declineReason": "Declined by CSR",
"leadDeliveredTimestamp": 1658312879
}
}Appointment scheduled event
This event occurs when the booking sent from the partner is converted to a job and the first appointment is scheduled.
POST: {st-prefix}/leads/appointment_scheduled (For example, https://api.partner.com/servicetitan/webhooks/leads/appointment_scheduled)
Name | Data Type | Notes |
scheduledStartTimestamp | integer | A timestamp of the scheduled appointment start time |
leadDeliveredTimestamp | integer | A timestamp when the booking is received from a partner on the initial booking creation request |
{
"partnerBookingId": "someBookingId",
"accountId": "someAccountId",
"profileId": "someProfileId",
"statusUpdateId": "uniqueValuePerRequest",
"status": "AppointmentScheduled",
"timestamp": 1658313884,
"eventData": {
"scheduledStartTimestamp": 1658401320,
"leadDeliveredTimestamp": 1658312877
}
}Appointment converted event
This event occurs when the booking sent from the partner is converted to a job and then marked as complete.
POST: {st-prefix}/leads/invoiced (For example, https://api.partner.com/servicetitan/webhooks/leads/invoiced)
Name | Data Type | Notes |
invoicedTimestamp | integer | A timestamp indicating the time (Unix epoch format) when a job, booked from a lead, has been marked as "COMPLETE." |
leadDeliveredTimestamp | integer | A timestamp indicating the time (Unix epoch format) when a lead, arrives and you can see it) in the user's ServiceTitan account. |
totalPrice | integer | The total price charged to an end customer as it is stated on the invoice. |
skus | integer | A list of unique identifiers for the various service tasks, materials, or equipment items. |
name | integer | The common or generic name used to identify a particular service task, material, or equipment item. |
code | integer | A specific code or number used to identify a particular service task, material, or equipment item |
price | integer | The cost of a particular service task, material, or equipment item, that is often listed in a standard currency such as dollars or euros. |
quantity | integer | The number of a particular service task, material, or equipment item available for purchase or is in inventory. |
serialNumber | integer | A unique identifier assigned specifically to a particular equipment item. |
model | integer | A specific model specifically for a particular equipment item. |
{
"partnerBookingId": "someBookingId",
"accountId": "someAccountId",
"profileId": "someProfileId",
"statusUpdateId": "uniqueValuePerRequest",
"status": "Invoiced",
"timestamp": 1658313865,
"eventData": {
"invoicedTimestamp": 1095379199,
"leadDeliveredTimestamp": 1095369188,
"totalPrice": 400.0,
"skus": [
{
"name": "some-service",
"code": "some-service-code",
"price": 20.0,
"quantity": 2.0
},
{
"name": "some-material",
"code": "some-material-code",
"price": 10.0,
"quantity": 3.0
},
{
"name": "some-equipment",
"code": "some-equipment-code",
"price": 110.0,
"quantity": 3.0,
"serialNumber": "abcdefg",
"model": "cool-equipment"
}
]
}
}Data models
Accounts update
Accounts update webhook payload example:

Availability update
Availability update webhook payload example:

Development guide
Major Data Flow Between ServiceTitan and Strategic Partner is presented in the graph below.

Job Type Mapping
A partner provides their Job Types (services) mapped to ServiceTitan-provided categories for the corresponding systems to speak the same "job type" language. Partner's job types serve as keys when pushing for their availability or whenever the partner sends a booking made for this particular job type to ServiceTitan. If there are categories that are not supported by the partner they can leave them blank. In the following you can see an example of a template that is provided to the Partner, filled out by them, and handed back to ServiceTitan to get input into our System.
Category | Partner Job Type Key |
|---|---|
HVAC | partner_job_type_1 |
HVAC | partner_job_type_2 |
Plumbing | partner_job_type_3 |
Plumbing | partner_job_type_4 |
Plumbing | partner_job_type_5 |
Electrician | partner_job_type_6 |
Electrician | partner_job_type_7 |
Garage Door | |
Garage Door | |
Garage Door |
Account Pairing
There are two Account Pairing mechanisms: Custom and OpenId Connect. OpenId Connect is the preferred one. If the strategic partner can not support it, then alternatively (but not preferably) they can proceed with the Custom mechanism.
OpenId Connect Pairing
Before learning more about the integration process, review some of the key terms used in this guide:
Partner: Strategic Partner integrating with ServiceTitan
Tenant: ServiceTitan clients and businesses utilizing the ServiceTitan platform
ServiceTitan Application: ServiceTitan portal where Tenants configure and manage their integrations
Partner Portal: Partner portal where Tenants authenticate and accept consent
Partner Integration Manager: An integration created in the ServiceTitan platform. Each integration must specify
client_id,client_secret, Authorization Endpoint, and Token Endpoint to use with OpenID ConnectAuthorization Endpoint: The URL where the Partner handles the authentication and authorization of the end user. This URL should be specified in Partner Integration Manager and should be publicly accessible
Token Endpoint: An endpoint on the Partner's side that is getting hit by ServiceTitan Application to exchange Authorization Code with tokens
Account Info Endpoint: Partner side endpoint to be hit by ServiceTitan on the Account information request
client_id: A unique key identifying Partner Integration. This value is considered public and will be passed in URLs during the authorization flow
client_secret: A secret value for Partner Integration. This value should be protected and is considered private
Integration of Tenant: A Partner Integration created by Tenant in the ServiceTitan Application
Leads Integration Platform allows to pair Tenant's account to the account they have on Partner side through OpenID Connect. For more information about the pairing mechanism and its description see the next diagram.

1. Credentials exchange
In the Credentials exchange step the Partner issues client_id and client_secret to ServiceTitan, which will be used later for Partner Integration pairing. Partner also provides Authorization Endpoint, Token Endpoint, Account Info Endpoint, and optionally a list of scopes.
2. Token acquiring
The Token acquiring step describes how tokens are acquired from Partners. It basically uses Authorization Code Flow described in the OpenID Connect specification. When Tenant clicks the Sign In with Partner button in ServiceTitan Application, ServiceTitan redirects them to Partner's Authorization Endpoint with the below parameters appended:
client_id: Client_id value specified in Step 1
response_type: Value for this parameter is always a code
response_mode: Value for this parameter is always a form_post (described in Form Post Response Mode)
scope: This parameter contains at least openid value. Other scope values may be present if specified in Partner Integration
state: Opaque value used to maintain state between the request and the callback. This parameter should be returned after redirecting to ServiceTitan Application
redirect_uri: ServiceTitan Application Uri to which Partner should redirect later with the Authorization Code
Example URL format provided by the Partner:
https://auth.partner.com/auth?
client_id=s6BhdRkqt3
&response_type=code
&scope=openid
&state=gy0ifjsldkj
&redirect_uri=https://servicetitan.com/callbackOnce the Tenant authenticates in Partner Portal and accepts consent (if necessary), Partner Portal sends POST request to redirect_uri with the following attributes:
"Content-Type" header with value: application/x-www-form-urlencoded
"Body" form parameters (key:value)
code: Authorization Code that will be used to obtain tokens
state: state parameter from initial request
Example Request:
POST https://servicetitan.com/callback
Content-Type: application/x-www-form-urlencoded
code=FghxlOBeZQQYbYS6WxSbUO
&state=gy0ifjsldkjLater to exchange Authorization Code with access-token and id-token, ServiceTitan Application sends POST request through the back-channel to the Partner's Token Endpoint with the following attributes:
"Authorization" header with the client_id and client_secret for Partner Integration joined by a ':', then base64 encoded
Authorization: Basic <Base64(client_id:client_secret)>
"Content-Type" header with value: application/x-www-form-urlencoded
"Body" form parameters (key:value)
client_id: client_id value specified in step 1
client_secret: client_secret value specified in step 1
code: Code received from Partner through a query parameter
grant_type: value for this parameter will always be authorization_code
redirect_uri: ServiceTitan Application Uri that was specified before
Example Request:
POST https://auth.partner.com/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic czZCaGRSa3FOMzpnWDFmQmF0M2JW
grant_type=authorization_code
&code=SplxlOBeZQQYbYS6WxSbIA
&redirect_uri=https://servicetitan.com/callbackPOST request to the token endpoint should return a JSON response that must include the access_token and id_token fields. The access_token can be leveraged to call the API on behalf of the account that granted the permissions.
Example Response Payload:
{
"access_token":
"zNLXAACWfCOb859MBGR12x4I67tWJB7y6eUQVdQT8zsLabBk8R",
"token_type": "Bearer",
"expires_in": 3600,
"id_token":
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Mzk1MTU5ODIsImlhdCI6MTYzOTUxMjM4Mis...",
}id_token must be JWT token and example of it's payload is the following:
{
"exp": 1639515982,
"iss": "https://example.com",
"sub": "rt67855b-7ed5-4556-8ff5-e15117b75ffd",
"aud": "84c96450-541f-4c94-9737-496173226d19",
"iat": 1639512382,
"accountInfo":
"{\"Status\":\"COMPLETED\",\"Account\":{\"Id\":\"BE3B293D-1028-4742-9004-7D7650D9569D\",\"Name\":\"MTech HVAC\",\"Profiles\":[{\"Id\":\"BE3B293D-1028-4742-9004-7D7650D9569D\",\"Name\":\"MTech HVAC\",},]}}"
}All claims in the above example are required except for "accountInfo". "accountInfo" claim must have the same structure as described in the 3rd step response payload. If id_token contains an "accountInfo" claim then pairing is finished at this point and the 3rd step is skipped.

3. Account pairing
The main pairing part takes place in the Account pairing step where ServiceTitan Application sends GET request to Partner's Account Info Endpoint with the following attributes:
"Authorization" header with base64 encoded access_token
Authorization: Bearer <Base64(access_token)>
Query parameters
request_id: unique value for account pairing which is set by ServiceTitan and should be returned if pairing is asynchronous
Example Request:
GET https://api.partner.com/account-info?request_id=FghxlOBeZQQYbYS6WxSbUOAuthorization: Bearer ek5MWEFBQ1dmQ09iODU5TUJHUjEyeDRJNjd0V0pCN3k2zVVRVmRRVDh6c0xhYkJrOFI=
Partner returns account information at this point which payload should contain COMPLETED status along with all the necessary account information for a successful pairing.
Example Response Payload:
{
"Status": "COMPLETED",
"RequestId": "Fghx1OBeZQQYbYS6WxSbUO",
"Account": {
"Id": "AccountId1",
"Name": "AccountName1",
"Profiles": [
{
"Id": "profileId1",
"Name": "Name1"
},
{
"Id": "profileId2",
"Name": "Name2"
}
]
}
}Partners can also decline pairing by sending DECLINED status in the payload.
Example Response Payload:
{
"Status": "DECLINED",
"RequestId": "Fghx1OBeZQQYbYS6WxSbUO"
}Custom Pairing
To enable partners to send leads to ServiceTitan for a particular tenant, we need a mechanism for pairing the tenant's account on our side with their account on the Partner's side. If the partner doesn't already have an auth mechanism to get authorized and pull the needed data, on behalf of the end-user for ServiceTitan, we can put in place a simple mechanism described below:

Partner Provides Endpoint to ServiceTitan: The endpoint looks like the following example https://x-partner.com/api/st/pair. This is the page where the tenant is redirected to when on the ServiceTitan Application the tenant clicks the sign-in or pair to make a bridge between their accounts in ServiceTitan and the Partner's side.
ServiceTitan appends a parameter to the URL: The parameter is requestId. The value for that parameter is set up by ServiceTitan and should not be modified by the partner. Later, the Partner will include that parameter and its value in the payload whenever they fire a call to send accounts/profiles information.
Tenant Sign-in: On the ServiceTitan Application side while the tenant sets up their integration with the Strategic Partner as a first step they hit a button to easily connect the 2 accounts on two sides.

Tenant Login: Once the tenant gets navigated to the Partner's page they use their login and password credentials to get authorized unless they are not already logged in.
The partner marks the Tenant (Service Provider) on their side and fires a call back to ServiceTitan to let ServiceTitan know that the Tenant went through the process (or not) and if the pairing is in PROCESSING or DECLINED status.
Account Pairing | status "Processing"
URL: https://leads-booking-api-demo.st.dev/api/integrations/accounts
Method: POST
Content-Type: application/json
Body:
{
"requestId": "{{requestId}}",
"status": "PROCESSING"
}Partner POSTs the Profiles payload to the given
callBackUrl: The login happens on the Partner's side; they can identify which user has logged in and can send the Profiles' info of that user to ServiceTitan as a payload tocallBackUrl.
Note: Requests sent to ServiceTitan need to get authorized. For more, see Server-to-server authentication.
Account Pairing | status "Completed"
URL: https://leads-booking-api-demo.st.dev/api/integrations/accounts
Method: POST
Content-Type: application/json
Body:
{
{
"requestId": "{{requestId}}",
"status": "COMPLETED",
"account": {
"id": "accountId",
"name": "account Name",
"profiles": [
{
"id": "profileId1",
"name": "profile Name 1"
},
{
"id": "profileId2",
"name": "profile Name 2"
},
{
"id": "profileId3",
"name": "profile Name 3"
}
]
}
}
}
Booking
ServiceTitan provides an endpoint for the Partner to send Bookings for a particular tenant's particular profile. The payload to be sent should look like this:
URL: https://leads-booking-api-demo.st.dev/api/integrations/bookings
Method: POST
Content-Type: application/json
{
"idempotencyToken":"{{idempotencyToken}}", // should be unique value
"partnerBookingId":"{{partnerBookingId}}", // should be unique value
"slot":{
"accountId":"{{accountId}}",
"profileId":"{{profileId}}",
"serviceId":"{{serviceId}}",
"startSec": 1234567890000,
"durationSec": 3600
},
"userInformation":{
"givenName":"FirstName",
"familyName":"LastName",
"telephone":"(999) 001-1126",
"email":"test.test@st.dev",
"address":{
"country":"US",
"locality":"Los Angeles",
"region":"CA",
"postalCode":"90029",
"streetAddress":"962 North Ardmore"
}
},
"description":"Here is some description text for this booking",
"extraDetails":{
"key": "value",
"key1": "value1",
"key2": "value2"
}
}Real Time Availability
Leads Integration Platform can provide availability slot updates through the webhooks. For more, see Availability update in the Webhooks section.
Testing
Login on Sandbox environment
Log in to the system as a tenant with the credentials provided to you by the ServiceTitan team
For example,
username - [Partner Integration]
password - [Partner]passOpen [Partner Integration] Settings
Go to the top toolbar and click Settings
.In the side panel, go to Integrations > Marketing Integrations.

Click Edit on [Partner Integration] card. The Authorization opens.
Add new Accounts
Clicking the Add Account button mimics the account pairing mechanism between ServiceTitan and the [Partner]. You can pair multiple accounts. In the screenshot above there is already an account setup. You can add as many accounts you want by clicking Add Account.

The Pair Now button click triggers a request to the backend. This helps you receive information on accounts in the response. You need account and profile IDs information for future booking requests sent to the system.

Note: In the sandbox environment the step for pairing is just mimicking the pairing mechanism, creating request_id and accounts information. For the Production environment, the accounts' information must be received from the [Partner].
API
Below you can find information on client_id, client_secret credentials, authorization token generation, and sending booking requests to our system.
Client Credentials
client_id: [Partner] _client
client_secret:
7a2abb98b5117e80500af07788109d1d2031784dbb6cc1833262f0ac2132Endpoints
Get Token
Endpoint: https://leads-identity-demo.st.dev
Body (x-www-form-urlencoded)
client_id:[Partner]_client
client_secret:
7a2abb98b5117e80500af07788109d1d2031784dbb6cc1833262f0ac2132
grant_type: client_credentials
Note: The token gets expired in an hourCreate Booking
Endpoint:
https://leads-booking-api-demo.st.dev/api/integrations/bookings
Method: POST
Authorization: "Bearer: <your_token_from_identity>"
Body template:
{
"idempotencyToken": "abcd123456",
"partnerBookingId": "12345abcd",
"slot": {
"accountId": "besthvaccompany",
"profileId": "besthvaccompany_0001",
"serviceId": "find_and_repair_leak",
"startSec": 1620744727,
"durationSec": 3600
},
"userInformation": {
"givenName": "John",
"familyName": "Smith",
"telephone": "(999) 001-1126",
"email": "email@em.ail",
"address": {
"country": "US",
"locality": "Atlanta",
"region": "CA",
"postalCode": "30339",
"streetAddress": "2450 Cumberland Pkwy"
}
},
"description": "Here is some description text for booking"
}