Introduction
This document is a specification of an API that Jobman would encourage suppliers to develop so that third-party services (like Jobman) can integrate behalf of shared customers.
For the purposes of this document, we’ll call the example supplier “Smith & Co”.
URI
Smith & Co would develop an API that can be reached at a publicly available URL:
https://api.smithco.com/
Headers
Make sure you have the following content type headers set on every request:
Accept: application/json
Content-Type: application/json
Errors
Smith & co uses conventional HTTP response codes to indicate the success or failure of an API request. The table below contains a summary of the typical response codes:
Example raw response including headers
HTTP/1.1 401 Unauthorized
Date: Tue, 12 Mar 2024 01:22:40 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: close
Server: nginx
X-Powered-By: PHP/8.3.3
Cache-Control: no-cache, private
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: X-RateLimit-Limit, X-RateLimit-Remaining
{"message":"No valid API Key was given."}
| Code | Description |
|---|---|
| 200 | Everything is ok. |
| 400 | Valid data was given but the request has failed. |
| 401 | No valid API Key was given. |
| 404 | The request resource could not be found. |
| 422 | The payload has missing required parameters or invalid data was given. |
| 429 | Too many attempts. |
| 500 | Request failed due to an internal error. |
| 503 | Offline for maintenance. |
Authentication
Smith & Co supports the OAuth 2.0 protocol for authorizing API requests. Authorized requests to the API should use an Authorization header with an access token obtained through the OAuth flow.
Authorization: Bearer <ACCESS_TOKEN>
This diagram shows the process of authorizing a user from start to finish.
1. Redirect Users
To initiate the authorization process, redirect users to
https://api.smithco.com/oauth/authorize
Provide the following query parameters:
| Key | Value |
|---|---|
| client_id | The client ID configured for your OAuth App |
| redirect_uri | The redirect URI configured for your OAuth App |
| scope | Space-separated list of scopes |
| state | An optional string to be passed back upon completion |
2. Handle User Authorization
If the user authorizes your application, Smith & Co will redirect to the specified redirect_uri.
This redirection will contain a temporary code query parameter. These authorization codes may only be exchanged once, and will expire after 10 minutes.
This redirection will also contain the previously passed state value, as a query parameter. If this state value does not match, the request may be compromised and you should abort the authorization
3. Exchange the authorization code for an access token
Make a POST request to:
https://api.smithco.com/oauth/token
The request body should include the following values:
| Key | Value |
|---|---|
| grant_type | authorization_code |
| code | The code you were provided in the previous step |
| redirect_uri | The redirect URI configured for your OAuth App |
| client_id | The client ID configured for your OAuth App |
| client_secret | The client secret configured for your OAuth App |
Note: Please avoid exposing your client secret
The returned response body should contain a JSON payload with the following key/value pairs
| Key | Value |
|---|---|
| access_token | The value represents the string to add to the Authorization header of future API requests |
| token_type | The value will be Bearer |
| expires_in | The value indicates the number of seconds until the access token will be invalid |
| refresh_token | The value indicates the string to use to generate another access token |
| scope | A space-separated string indicating the scopes that the access token can use |
Use the generated access_token value to make API requests on behalf of the authorized user.
User
Get user details
Response
{
"success": true,
"message": "OK",
"result": {
"id": "CUSTOMER0001",
"name": "Acme Inc",
"email": "sales@acmeinc.com"
}
}
This endpoint retrieves the account information of the authenticated customer.
HTTP Request
GET https://api.smithco.com/v1/user
Products
Get all Products
Response
{
"success": true,
"message": "OK",
"result": [
{
"product_code": "PRODUCT0001",
"description": "Door Hinge",
"stock_type": "Hinge",
"colour": "Black",
"finish": "Gloss",
"range": "Premium",
"unit_price": "1.250",
"length": "100",
"width": "250",
"thickness": "20",
"rate_type": "ea",
"product_url": "https://smithco.com/products/hinges/product-0001",
"product_image_url": "https://smithco.com/images/product-0001-small.jpg",
"qty_in_stock": "100",
"qty_in_stock_locally": "30",
"qty_in_stock_interstate": "70",
"lead_time_days": "3",
"restock_lead_time_days": "31"
},
{
"product_code": "PRODUCT0002",
"description": "Door Hinge",
"stock_type": "Hinge",
"colour": "Black",
"finish": "Matt",
"range": "Premium",
"unit_price": "1.250",
"length": "100",
"width": "250",
"thickness": "20",
"rate_type": "ea",
"product_url": "https://smithco.com/products/hinges/product-0002",
"product_image_url": "https://smithco.com/images/product-0002-small.jpg",
"qty_in_stock": "100",
"qty_in_stock_locally": "30",
"qty_in_stock_interstate": "70",
"lead_time_days": "3",
"restock_lead_time_days": "31"
}
]
}
Return a list of all products (can potentially contain pricing and availability specific to that customer).
HTTP Request
GET https://api.smithco.com/v1/products?page=<PAGE>
Get a specific Product
Response
{
"success": true,
"message": "OK",
"result": {
"product_code": "PRODUCT0002",
"description": "Door Hinge",
"stock_type": "Hinge",
"colour": "Black",
"finish": "Matt",
"range": "Premium",
"unit_price": "1.250",
"length": "100",
"width": "250",
"thickness": "20",
"rate_type": "ea",
"product_url": "https://smithco.com/products/hinges/product-0002",
"product_image_url": "https://smithco.com/images/product-0002-small.jpg",
"qty_in_stock": "100",
"qty_in_stock_locally": "30",
"qty_in_stock_interstate": "70",
"lead_time_days": "3",
"restock_lead_time_days": "31"
}
}
Get information about a specific product.
HTTP Request
GET https://api.smithco.com/v1/products/<PRODUCT_ID>
Orders
Get all Orders
Response
{
"success": true,
"message": "OK",
"result": [
{
"id": "ORDER0001",
"status": "Shipped",
"po_number": "PO0000289272",
"order_date": "2024-01-22",
"requested_by": "John Smith",
"requested_email": "john@acmeinc.com",
"total": "187500.00",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
"unit_price": "1250",
"subtotal": "125000.00"
},
{
"product_code": "PRODUCT0002",
"quantity": "50",
"unit_price": "1250",
"subtotal": "62500.00"
}
]
},
{
"id": "ORDER0002",
"status": "Placed",
"po_number": "PO0000282222",
"order_date": "2024-01-22",
"requested_by": "John Smith",
"requested_email": "john@acmeinc.com",
"total": "13125.00",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
"unit_price": "12.50",
"subtotal": "12500.00"
},
{
"product_code": "PRODUCT0002",
"quantity": "50",
"unit_price": "12.50",
"subtotal": "625.00"
}
]
}
]
}
Return a list of all orders that a customer has placed.
HTTP Request
GET https://api.smithco.com/v1/orders?page=<PAGE>
Get a specific Order
Response
{
"success": true,
"message": "OK",
"result": {
"id": "ORDER0002",
"status": "Placed",
"po_number": "PO0000282222",
"order_date": "2024-01-22",
"requested_by": "John Smith",
"requested_email": "john@acmeinc.com",
"total": "13150.00",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
"unit_price": "12.50",
"subtotal": "12500.00"
},
{
"product_code": "PRODUCT0002",
"quantity": "50",
"unit_price": "12.50",
"subtotal": "625.00"
}
]
}
}
Get information about a specific order.
HTTP Request
GET https://api.smithco.com/v1/orders/<ORDER_ID>
Place a new order
Request (minimum)
{
"po_number": "PO0000282222",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
},
{
"product_code": "PRODUCT0002",
"quantity": "50",
},
]
}
Response (minimum)
{
"success": true,
"message": "OK",
"result": {
"id": "ORDER0003",
"status": "Placed",
"po_number": "PO0000282222",
"total": "13750.00",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
"unit_price": "12.50",
"subtotal": "12500.00"
},
{
"product_code": "PRODUCT0002",
"quantity": "50",
"unit_price": "12.50",
"subtotal": "625.00"
}
]
}
}
This endpoint allows a customer to place a new order.
HTTP Request
POST https://api.smithco.com/v1/orders
This is a list of fields that are available to be sent for the purchase order. Items without an asterisk are optional.
| Parameter | Required | Eg. | Description |
|---|---|---|---|
| po_number | * | PO0000282222 | The purchase order number |
| items | * | (Array, see Items below) | Array of product details required |
| order_date | 2024-01-20 | The date the order was created inside Jobman (which may be different to the day it was placed with the supplier) | |
| required_by_date | 2024-01-30 | The date this order is required by | |
| requested_by_name | John Smith | The name of the person placing the order | |
| requested_by_email | john@acmeinc.com | The email of the person placing the order | |
| delivery_street_no | 15 | Street number of the delivery address | |
| delivery_street_name | Railway St | Street name of the delivery address | |
| delivery_city | Gnomesville | Suburb (City) of the delivery address | |
| delivery_region | Western Australia | Region (State) of the delivery address | |
| delivery_postcode | 6000 | Postcode (Zip) of the delivery address | |
| delivery_country | Australia | Country of the delivery address | |
| delivery_instructions | Deliver to side roller door | Indicate specific delivery instructions for this order |
Items
This is a list of fields that are available for each item. Items without an asterisk are optional.
| Parameter | Required | Eg. | Description |
|---|---|---|---|
| product_code | * | FM-947818 | The product code identifier for the product |
| quantity | * | 2 | The quantity that is requested |
| job_number | 1234.2 | A string that identifies which job the product is required for | |
| index | 1 | A numerical index to keep the items in the correct order | |
| required_by_date | 2024-01-29 | Date that the line item is required by |
Request (maximum)
{
"po_number": "PO0000282222",
"order_date": "2024-01-20",
"required_by_date": "2014-01-30",
"requested_by_name": "John Smith",
"requested_by_email": "john@acmeinc.com",
"delivery_street_no": "15",
"delivery_street_name": "Railway St",
"delivery_city": "Gnomesville",
"delivery_region": "Western Australia",
"delivery_postcode": "6000",
"delivery_country": "Australia",
"delivery_instructions": "Please deliver to side roller door.",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
"job_number": "1234.2",
"index": 1,
"required_by_date": "2024-01-30"
},
{
"product_code": "PRODUCT0002",
"quantity": "50",
"job_number": "1234.1A",
"index": 2,
"required_by_date": "2024-01-31"
}
]
}
Response (maximum)
{
"success": true,
"message": "OK",
"result": {
"id": "ORDER0003",
"status": "Placed",
"po_number": "PO0000282222",
"required_by_date": "2014-01-30",
"requested_by_name": "John Smith",
"requested_by_email": "john@acmeinc.com",
"delivery_street_no": "15",
"delivery_street_name": "Railway St",
"delivery_city": "Gnomesville",
"delivery_region": "Western Australia",
"delivery_postcode": "6000",
"delivery_country": "Australia",
"delivery_instructions": "Please deliver to side roller door.",
"total": "13750.00",
"sales_tax": "1375.00",
"total_inc_tax": "15125.00",
"items": [
{
"product_code": "PRODUCT0001",
"quantity": "1000",
"job_number": "1234.2",
"index": 1,
"required_by_date": "2024-01-30",
"estimated_arrival_date": "2024-01-26",
"unit_price": "12.50",
"subtotal": "12500.00",
"sales_tax": "1250.00",
"subtotal_inc_tax": "13750.00"
},
{
"product_code": "PRODUCT0002",
"quantity": "100",
"job_number": "1234.1A",
"index": 2,
"required_by_date": "2024-01-31",
"estimated_arrival_date": "2024-01-26",
"unit_price": "12.50",
"subtotal": "1250.00",
"sales_tax": "125.00",
"subtotal_inc_tax": "1375.00"
}
]
}
}