ABS Partner Integration API Guide - abs-warranty/integrations GitHub Wiki
Welcome to the ABS Partner API Doc.
The URL for the API is https://data.absintegrations.com. There will be a version number, endpoint and company name added to the end of the URL for each partner so your API URL will look like
https://data.absintegrations.com/v2/partners/tirecompany.
The API uses a very simple REST protocol that, once authorized, just takes a FORM POST with some authorization info in the headers and a JSON representation of the data being sent in the body of the POST.
For authentication ABS uses standard JWT tokens encrypted with a secret key that ABS will provide. We use the HS256 encryption format and will assign a partner id to be sent as a JWT claim. Think of the way we use JWTs as modern API keys without the security exposure of basic authentication. JWTs can be created by most web development libraries and can be tested out at sites like this one:
If your systems are not equipped to handle JWT token-based authentication, please contact us to discuss simpler but less secure options.
ABS will assign each partner a client secret (a long string of random numbers) and a partner id.
Using standard web development libraries, the partner will generate a JWT token using the assigned secret with partnerid: and claimdate: in the claims (a standard in JWT).
The partner will call the API with a standard HTTP POST that has the following Headers set:
header 'authorization: Bearer <JWT Token>'
header 'content-type: application/json'
If anything goes wrong with the Authentication the API will return 401 (Unauthorized)
The body of the post will be a JSON representation of the object being passed (Registrations, Claims, Sales or Cancellations) and the fields listed below in the data dictionary.
Numbers should be passed as true numbers to make validation simpler, strings will be quoted as standard JSON.
Return code will be standard HTTP Status codes with more information about each post as JSON in the body
-
200 (Success)
Successful POST, all records written -
206 (Partial Content)
A post with multiple records had some written and some rejected. The body will be a JSON array of the records accepted and the the fields that caused errors -
400 (Bad Request)
The POST was missing required fields or all records were rejected. The body will be a JSON array of the fields that caused the error -
401 (Unauthorized)
Failed authorization, check your Partner ID and JWT Token
While testing and debugging you can read and write from testing tables rather than the production ones. This will keep testing data nicely segregated. All you need to do is POST to partners/mycompany_test
rather than partners/mycompany
the url like this:
https://data.absintegrations.com/v2/partners/tirecompany_test
The API accepts four main record types, they may not all be applicable to your use case.
- Registrations
- Cancellations
- Claims
- Sales
Some key logic to understand:
- A Registration can only be cancelled once
- Claims can only be submitted to a valid registration (not cancelled, not expired)
- Claims can only be submitted to a registration if there are still tires insured on the claim
Below is a list of our standard tables and their fields. If your system can’t generate each of these or if your system has key fields not listed, please contact ABS to discuss your specifics.
The Field Name listed below will be the JSON label for the application/json body of the POST to the API.
- Note: Only send in one registration per invoice. If you sell more than one of the same tire, use TireCount and the DOT1, DOT2 etc fields. Resending the same ShopID and InvoiceNumber will update the registration, not add a new one.
Field Name | Field Desc | Data Type | Required | Notes |
---|---|---|---|---|
OrgID | Organization ID | string (50) | N | Optional field for grouping things like ownership groups. Will be blank if not passed in |
ShopID | Dealer/Store/Shop ID | string(25) | Y | Shop where the tires were sold |
InvoiceNumber | Invoice Number | string(50) | Y | Invoice for the registration |
PlanEnrollDate | Plan Enroll Date | datetime | Y | Date of enrollment |
EmployeeID | Employee ID | string(50) | Y | To track individual responsible for TPP sale |
CustomerID | Customer ID | String(50) | Y | Enables data to be filtered by individual customer (could be customer name or customer id number) |
VehicleYear | Vehicle Year | string(25) | Four-digit year | |
VehicleMake | Vehicle Make | string(25) | ||
VehicleModel | Vehicle Model | string(25) | ||
VIN | VIN | string(50) | If available | |
CurrentMileage | Current Vehicle Mileage | int | Mileage at time of TPP registration/sale | |
TiresCovered | Count of Tires Covered | int | Y | How many tires are covered on this registration |
TPPPrice | TPP Price | money | Y | TPP Price Per Tire |
TireBrand | Tire Make/Brand | string(25) | Y | For all tire sales with an attached TPP |
TireModel | Tire Model | string(25) | “” | |
TireSize | Tire Size | string(25) | Y | “” |
TirePrice | Tire Retail Price | money | Y | Tire Retail Price Per Tire |
TireCost | Tire Wholesale Price | money | Y | Tire Wholesale Cost Per Tire |
TireDOT1 | TireDOT1 | string(25) | Y | For all tire sales with an attached TPP / if available |
TireDOT2 | TireDOT2 | string(25) | “” | |
TireDOT3 | TireDOT3 | string(25) | “” | |
TireDOT4 | TireDOT4 | string(25) | “” | |
TireDOT5 | TireDOT5 | string(25) | “” | |
TireDOT6 | TireDOT6 | string(25) | “” | |
CommercialVehicle | Commercial Vehicle | string(5) | Yes or No (Default is No) |
Field Name | Field Desc | Data Type | Required | Notes |
---|---|---|---|---|
OrgID | Organization ID | string (50) | N | Optional field for grouping by things like ownership groups. Will be blank if not passed in |
ShopID | Dealer/Store/Shop ID | string(25) | Y | Shop where the registration was sold |
InvoiceNumber | Repair Invoice Number | string(25) | Y | Invoice Number for the original registration sale |
ClaimDate | Claim Date | datetime | Y | Date of claim |
RepairShopID | Original Store / ShopID | string(25) | Y | Shop ID where the repair was performed |
RepairlnvoiceNumber | Original Invoice Number | string(50) | Y | Invoice from the repair work |
VIN | VIN | string(50) | If available | |
VehicleMileage | Vehicle Mileage at Time of Claim | int | Mileage at the time of repair | |
TireClaimCount | Count of Tires in Claim | int | Y | How many tires were repaired |
CreditAmount | Amount Credited to Customer (Total) | money | Y | Discount amount * quantity |
CostPerUnit | Amount the Claim Cost Per Unit | money | Y | Replacement cost per tire at time of repair |
TireLocation1 | Location of tire 1 on vehicle | string(200) | Ex. “front passenger” or “right front” | |
TireLocation2 | Location of tire 2 on vehicle | string(200) | "" | |
TireLocation3 | Location of tire 3 on vehicle | string(200) | "" | |
TireLocation4 | Location of tire 4 on vehicle | string(200) | "" | |
TireLocation5 | Location of tire 5 on vehicle | string(200) | "" | |
TireLocation6 | Location of tire 6 on vehicle | string(200) | "" | |
ServiceDescription | Service Classification / Description | string(200) | i.e., "sidewall" or "screw in tread" - incorporate dropdown into POS screen? | |
TireBrand | Replacement Tire Make/Brand | string(25) | Y | |
TireModel | Replacement Tire Model | string(25) | ||
TireSize | Replacement Tire Size | string(25) | Y | |
TireCost | Replacement Tire Price | money | Y |
Note on Claims: To accommodate retransmissions any claim with identical OrgID, ShopID, InvoiceNumber, RepairShopID and RepairInvoiceNumber will be treated as an update, not a new claim.
Field Name | Field Desc | Data Type | Required | Notes |
---|---|---|---|---|
OrgID | Organization ID | string (50) | N | Optional field for grouping by things like ownership groups. Will be blank if not passed in |
ShopID | Dealer/Store/Shop ID | string(25) | Y | Shop that made the sale |
InvoiceNumber | Sale Invoice Number | string(25) | Y | Invoice number for the sale |
SaleDate | Date Sold | datetime | Y | Date of the sale |
TireCount | Count of Tires Covered | int | Y | Number of tires sold |
TireBrand | Tire Make/Brand | string(25) | Y | for all tire sales with and without an attached TPP |
TireModel | Tire Model | string(25) | “” | |
TireSize | Tire Size | string(25) | Y | “” |
TirePrice | Tire Retail Price | money | Y | “” what customer pays |
TireCost | Tire Wholesale Price | money | Y | “” what shop pays |
Field Name | Field Desc | Data Type | Required | Notes |
---|---|---|---|---|
OrgID | Organization ID | string (50) | N | Optional field for grouping. For example ownership group. Blank if not passed in |
ShopID | Dealer/Store/Shop ID | string(25) | Y | Shop ID from original sale and registration |
InvoiceNumber | Sale Invoice Number | string(25) | Y | Invoice from the original sale and registration |
CancelShopID | Dealer/Store/Shop ID | string(25) | Y | Shop ID where the tire registrations were cancelled |
CancelInvoiceNumber | Sale Invoice Number | string(25) | Y | Invoice from the the shop where tire registrations were cancelled |
TireCancelCount | Count of Tires Cancelled | int | Y | How many tires were cancelled |
CancelDate | Date Cancelled | datetime | Y | Date of the cancellation |
Note on Cancellations: To accommodate retransmissions any cancellation with identical OrgID, ShopID, InvoiceNumber, CancelShopID and CancelInvoiceNumber will be treated as an update, not a new cancellation.
Numeric Data: ABS can usually convert from string representations to appropriate numbers.
Date Time: All dates should be ISO 8601 format YYYYMMDDTHH:MM:SS in UTC time zone preferably or with designated offset from UTC. If your system is always synced to a specific time zone let us know and we can create a custom import based on a static time zone.
Money: Money / dollar amounts should be numeric with 2 decimal point precision or a matching string representation.
If any of data fields are required and empty or malformed, the API will return a HTTP status 400 “Bad Request”. It should be easy to determine which fields are not present in the JSON data or badly formed, feel free to contact us if seemingly valid data is being rejected.
Call the API with the JWT as bearer token and a content type of application/json with the data in the body. Each call should give you a 200 success with “Successfully Posted” as the response.
curl --request POST \
--url https://data.absintegrations.com/v2/partners/[companyName] \
--header 'authorization: Bearer eyJhb...SQj6A' \
--header 'content-type: application/json' \
--data {
"Registrations": [
{
"ShopID": "005308",
"InvoiceNumber": "1044273",
"PlanEnrollDate": "2018-12-04",
"EmployeeID": "JP0078",
"CustomerID": "5108-460340",
"VehicleYear": "08",
"VehicleMake": "GMC TRUCK",
"VehicleModel": "SIERRA 1500 PICKUP",
"VIN": "2GTEC19C481101249",
"CurrentMileage": "187437",
"TiresCovered": 4,
"TPPPrice": 995.68,
"TireBrand": "NIT",
"TireModel": "P265/65R18 112T NITTO CROSSTEK 2",
"TireSize": "2656518",
"TirePrice": 188.99,
"TireCost": 105.98,
"TireDOT1": "DOT 73C2 KLH0913",
"CommercialVehicle": "false"
}]}
curl --request POST \
--url https://data.absintegrations.com/v2/partners/[companyName] \
--header 'authorization: Bearer eyJhb...SQj6A' \
--header 'content-type: application/json' \
--data {
"Claims": [
{
"ShopID": "0056678",
"InvoiceNumber": "35554367",
"ClaimDate": "2020-01-27",
"ShopID": "0056698",
"InvoiceNumber": "9994498",
"VehicleMileage": 96192,
"TireClaimCount": 4,
"CreditAmount": 64.04,
"CostPerUnit": 60.00,
"ServiceType": "REPLACE",
"ServiceDescription": "FLAT REPAIR PASSENGER REAR",
"TireBrand": "SUM",
"TireModel": "235/60R18/XL 107V HTR A/S P02 BLK",
"TireSize": "2356018",
"TireCost" : 58.00
}]}
curl --request POST \
--url https://data.absintegrations.com/v2/partners/[companyName] \
--header 'authorization: Bearer eyJhb...SQj6A' \
--header 'content-type: application/json' \
--data {
"Sales": [
{
"ShopID": "005054568",
"InvoiceNumber": "354365667",
"SaleDate": "2020-01-27",
"TireCount": 4,
"TireBrand": "SUM",
"TireModel": "235/60R18/XL 107V HTR A/S P02 BLK",
"TireSize": "2356018",
"TirePrice": 225.09,
"TireCost": 195.09
}]}
curl --request POST \
--url https://data.absintegrations.com/v2/partners/[companyName] \
--header 'authorization: Bearer eyJhb...SQj6A' \
--header 'content-type: application/json' \
--data {
"Cancellations": [
{
"ShopID": "005054568",
"InvoiceNumber": "354365667",
"CancelShopID": "005054568",
"CancelInvoiceNumber": "365365167",
"TireCancelCount": "1",
"CancelDate": "2020-01-27"
}]}
All four data items (Registrations, Claims, Sales and Cancellations) can also be queried back with a simple HTTP GET request. Use the same authorization header and include the following:
Field Name | Values | Required |
---|---|---|
rec | registrations, claims, sales or cancellations | One of these 4 must be in the GET request |
OrgID | A valid OrgID if you are using them | No |
ShopID | A valid ShopID | Yes |
InvoiceNumber | A valid InvoiceNumber | Yes |
- Note: All dates will be in RFC339 Format "2018-12-04T00:00:00Z"
curl --location --request GET https://data.absintegrations.com/v2/partners/[companyname]?rec=registrations&partnerid=[partnerid]&shopid=12345&invoicenumber=12345 \
--header 'content-type: application/json' \
--header 'Authorization: Bearer eyJhbG...ciOiJI'
returns
{
"PartnerID": 1001,
"OrgID": "",
"ShopID": "005108",
"InvoiceNumber": "104252",
"PlanEnrollDate": "2018-12-04T00:00:00Z",
"EmployeeID": "JP006",
"CustomerID": "5108-491514",
"VehicleYear": "08",
"VehicleMake": "LEXUS",
"VehicleModel": "IS 250",
"VIN": "JTHBK262X82078324",
"CurrentMileage": 175920,
"TiresCovered": 2,
"TPPPrice": 322.18,
"TireBrand": "SUM",
"TireModel": "225/40R18/XL 92W SUMITOMO HTR A/S P02",
"TireSize": "2254018",
"TirePrice": 104.98,
"TireCost": 74.01,
"TireDOT1": "",
"TireDOT2": "",
"TireDOT3": "",
"TireDOT4": "",
"TireDOT5": "",
"TireDOT6": "",
"CommercialVehicle": "false"
}
curl --location --request GET https://data.absintegrations.com/v2/partners/[companyname]?rec=claims&partnerid=[partnerid]&shopid=12345&invoicenumber=12345 \
--header 'content-type: application/json' \
--header 'Authorization: Bearer eyJhbG...ciOiJI'
returns
{
"PartnerID": 1001,
"OrgID": "",
"ShopID": "005108",
"InvoiceNumber": "104155",
"ClaimDate": "2020-01-27T00:00:00Z",
"RepairShopID": "005108",
"RepairInvoiceNumber": "104273",
"VIN": "",
"VehicleMileage": 96192,
"TireClaimCount": 4,
"CreditAmount": 64.04,
"CostPerUnit": 60,
"ServiceType": "REPLACE",
"ServiceDescription": "",
"TireLocation1": "",
"TireLocation2": "",
"TireLocation3": "",
"TireLocation4": "",
"TireLocation5": "",
"TireLocation6": "",
"TireBrand": "SUM",
"TireModel": "235/60R18/XL 107V SUMITOMO HTR A/S P02 BLK",
"TireSize": "2356018",
"TirePrice": 0,
"TireCost": 58.94
}
curl --location --request GET https://data.absintegrations.com/v2/partners/[companyname]?rec=cancellations&partnerid=[partnerid]&ShopID=12345&InvoiceNumber=12345 \
--header 'content-type: application/json' \
--header 'Authorization: Bearer eyJhbG...ciOiJI'
returns
{
"PartnerID": 1001,
"OrgID": "",
"ShopID": "005108",
"InvoiceNumber": "104283",
"CancelShopID": "005108",
"CancelInvoiceNumber": "104283",
"CancelDate": "2020-01-27T00:00:00Z"
}
curl --location --request GET https://data.absintegrations.com/v2/partners/[companyname]?rec=sales&partnerid=[partnerid]&ShopID=12345&InvoiceNumber=12345 \
--header 'content-type: application/json' \
--header 'Authorization: Bearer eyJhbG...ciOiJI'
returns
{
"PartnerID": 1001,
"OrgID": "",
"ShopID": "005058",
"InvoiceNumber": "354404",
"SaleDate": "2020-01-27T00:00:00Z",
"TireCount": 1,
"TireBrand": "",
"TireModel": "",
"TireSize": "",
"TirePrice": 99.99,
"TireCost": 78.16
}
This is a special call to check on the status of a registration, call it just like GET Registration but it also returns the current status and number of tires left on the registration.
Possible values for WarrantyStatus
- Registration is Active
- Registration is Cancelled
- No Tires left on Registration
- Registration is Expired
Notes:
- TiresCovered is the original number of Tires Covered from the Registration
- TireClaimCount is the total claimed so far
- TireCancelCount is the total cancelled so far
- TiresLeft is the number left on the registration
curl --location --request GET https://data.absintegrations.com/v2/partners/[companyname]?rec=registrationstatus&partnerid=[partnerid]&ShopID=12345&InvoiceNumber=12345 \
--header 'content-type: application/json' \
--header 'Authorization: Bearer eyJhbG...ciOiJI'
returns:
{
"RegistrationID": 70,
"PartnerID": 1001,
"OrgID": "",
"ShopID": "005108",
"InvoiceNumber": "104252",
"PlanEnrollDate": "2018-12-04T00:00:00Z",
"CreatedDate": "2018-11-04T00:00:00Z",
"TiresCovered": 2,
"TireClaimCount": 0,
"TireCancelCount": 0,
"TiresLeft": 2,
"WarrantyStatus": 1,
"CancelDate": "",
"ExpireDate": "",
"StatusDate": "",
"Message": "Registration is Active"
}
-
200 (Success)
The record was retrieved and the requested record will be a JSON object in the body. -
400 (Bad Request)
Required fields are missing, a listing of the expected fields will be in the body as JSON. -
204 (No Content)
The GET request had the proper format but that does not match any records in the database. The body will be blank.
Special needs
ABS is here to make the data transfer process simple and friction free, please reach out to [email protected] if you need any help getting this data feed set up.