OperationsCommander - https://opscom.wiki

API Documentation

Our APIs give third-parties the ability to easily integrate with the OPSCOM platform. 

OperationsCommander (OPSCOM) has made APIs (Application Programming Interface) available that allow for authenticated third-parties to access and manipulate data in OPSCOM as needed. This enables the accomplishment of specific functions, such as the ability to add valid permits from pay-and-display machines.

What is an API?

APIs, or "Application Programming Interfaces," are specially-designed channels for communication between software systems. Essentially, they give programmers the ability to connect your custom software application to an external system, whether it is running within your office space or out in the cloud.

When you have multiple software systems within your business, it can require a lot of duplicate data entry, which costs you time and money. The API integration project aims to save you money by reducing excess data entry by making it easy for your staff to maintain multiple databases from a single location. 

Vendors program APIs into their software to allow external developers to access and manipulate their data. The third-party integration project aims to utilize these systems to eliminate excess data entry and provide new features to the software.

Please note this documentation is specific to APIs we have developed for third-parties to connect to OPSCOM.

We also offer API integration for other third-party hardware and software vendors.

API Error Codes

API error codes indicate a failure while communicating with the OPSCOM API.

Example Error

Content-Type: application/json

{
    "ErrorCode": 9001,
    "ErrorMessage""API Token is missing from the request."
}

Error Codes

Error Code Error Message
9000 Client Code is missing from the request.
9001 API Token is missing from the request.
9002 The supplied API token does not have permission to perform that request.
9003 Could not parse the request.
9004 End Time is a required field.
9005 The end time value is invalid.
9006 Plate is a required field.
9007

The start time value is invalid.

9008 Reference ID is required. On a new permit push, a reference id is returned. This is required for updates and deletes.
9009 Record not found. 
9010 The Plate Type is required.
9011 The province or state is required.
9012 The vehicle is already in the database. 
9013 A unique id is required.
9014 The login source is required.
9015 The login source is invalid.
9016 The user e-mail is required.
9017 The user's first name is required.
9018 The user's last name is required.
9019 The user's email address must be unique.
9020 The user's username must be unique.
9021 The vehicle's plate length exceeds 50 characters.
9022 A record already exists with the supplied details.
9030 The field's maximum number of characters was exceeded.
9031 The field is required.
9032 The field has a minimum number of characters.

9033

The field's value is invalid.

9034

The API Token does not exist for the specified client.

Permits API

Permits API

Pull API: Permit Stats

The OPSCOM Controller provides a simple JSON based API to integrate with. Clients use this API to gather stats on permits pushed into OPSCOM.

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

Making API Requests 

Make sure you set the HTTP Content-Type header to be application/json.        

Raw Request:
POST /api/OC-TOMA/v1/permits/stats HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
    "zones": "NOT-REQUIRED--LIST-OF-ZONES"
}
JavaScript Request
var request = new XMLHttpRequest();
 
request.open('POST''https://controller.operationscommander.io/api/OC-TOMA/v1/permits/stats');
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN",
    "zones""Lot 01,Lot 02"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute
Type

Limits

Possible Names
Description
apiToken String

50-character alphanumeric including dashes

apiToken (Required) Your supplied API Token.

zones

String Listed zones match zone names in database

zones

(Not Required) Comma delimited list of zones

e.g. zone1,zone2,Lot 03,Red Lot,Street parking

Successful Response

The response will be a json object. The same reference id will be returned.

Content-Type: application/json

{
    "data": [
        {
            "type""standard",
            "zone""zone1",
            "total""4"
        },
        {
            "type""temp",
            "zone""zone1",
            "total""35"
        },
   :
   :
}
Permits API

Push API: Permit Delete

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

The OPSCOM Controller provides a simple JSON based API to integrate with. Clients use this API to directly feed details about existing paid permits and their changes into OPSCOM from other systems such as Parking apps.  

Make sure you set the HTTP Content-Type header to be application/json.

Making API Requests

Raw Request:

POST /api/OC-TOMA/v1/permits/delete HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
    "referenceID": "PREVIOUS-REFERENCE-ID"
}

JavaScript Request:

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN",
    "referenceID""PREVIOUS-REFERENCE-ID"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute Type

Limits

Possible Names
Description
apiToken String

50-character alphanumeric including dashes

apiToken (Required) Your supplied API Token.

Reference ID

String 50-character alphanumeric including dashes

referenceid

referenceID

reference_id

(Required) This value is supplied to when the permit push api is successful.

e.g. 1a9b5375-cb75-4c71-9939-eeae550b09ac

Successful Response

The response will be a json object. The same reference id will be returned.

Content-Type: application/json

{
    "status""success",
    "reference_id""1a9b5375-cb75-4c71-9939-eeae550b09ac",
    "InternalReferenceID""1a9b5375-cb75-4c71-9939-eeae550b09ac"
}
Permits API

Push API: Permit Create

The Push API: Permit Create allows OPSCOM administrators to integrate external parking systems directly with the OPSCOM Controller. This RESTful integration automatically synchronizes paid or temporary permit details from third-party hardware and software, such as parking meters, pay stations, and mobile parking applications. By pushing active parking instances into the centralized database, administrators ensure real-time compliance tracking and seamless enforcement across all connected devices.

Setup and Configuration

Before third-party systems can transmit transaction data into the system, specific environmental settings and authorization keys must be established.

API access is a premium paid feature that requires licensing activation. Organizations must contact their OPSCOM Account Executive to negotiate access and enable the endpoint interface for their environment.

Admin Side Configuration

  1. Secure an authenticated API token from your OPS-COM technical representative.

  2. Confirm that all target parking zones match your external hardware naming conventions. Review configuration rules on the Parking Zone Administration page to avoid disconnected reporting errors.

  3. Distribute the production endpoint URL and unique alphanumeric token to your third-party integration developers or vendors (e.g., HotSpot).

Using this Feature

The integration relies on an external system triggering HTTP POST requests to the centralized server. The endpoint accepts a standard structured JSON payload containing authorization, vehicle identity, and time boundaries.

Endpoint Address

POST [https://controller.operationscommander.io/api/OC-TOMA/v1/permits/push](https://controller.operationscommander.io/api/OC-TOMA/v1/permits/push)

Request Header Requirements

External systems must supply the following exact headers within every network transmission:

Request Payload Examples

Raw HTTP Request

HTTP

POST /api/OC-TOMA/v1/permits/push HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache

{
    "apiToken": "YOUR-API-TOKEN",
    "Amount": "14.50",
    "CurrencyID": "CAD",
    "LicencePlate": "PL8RDR",
    "zone": "Lot 4",
    "permitNo": "L4-1138",
    "startTime": "2018-07-02T09:00:00",
    "endTime": "2018-07-02T09:30:00",
    "promoCode": "DISCOUNT20"
}

JavaScript XMLHttpRequest Example

JavaScript

var request = new XMLHttpRequest();

request.open('POST', 'https://controller.operationscommander.io/api/OC-TOMA/v1/permits/push');

request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Accept', 'application/json');

request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:', this.status);
    console.log('Headers:', this.getAllResponseHeaders());
    console.log('Body:', this.responseText);
  }
};

var body = {
    "apiToken": "YOUR-API-TOKEN",
    "Amount": "14.50",
    "CurrencyID": "CAD",
    "LicencePlate": "PL8RDR",
    "zone": "Lot 4",
    "permitNo": "L4-1138",
    "startTime": "2018-07-02T09:00:00",
    "endTime": "2018-07-02T09:30:00",
    "promoCode": "DISCOUNT20"
};

request.send(JSON.stringify(body));

Request Object Attributes

The endpoint processes incoming data objects using strict key names. Use the definitions below to map external database variables correctly.

Attribute Type Limits Possible Names Required / Optional Description
apiToken String

50-character alphanumeric including dashes

apiToken Required The unique system token supplied by OPSCOM for validation.
LicensePlate String 25-characters

plate

LicencePlate

Required The license plate of the vehicle receiving the parking permission.
Amount String 9-character decimal

amount

Amount

Optional

Transaction amount. Must contain at least 3 digits, two of which are penny values.

The minimum allowable value is $0.01, and the maximum allowable value is $999999.99.

CurrencyID String 10-characters

currency

CurrencyID

Optional Transaction currency type. Supported defaults include CAD or USD.

Start Date

String

20-characters


startTime

StartDateUtc

Required

Must be in the format of Y-m-d\TH:i:s

e.g. 2000-05-30T14:38:22

For formatting help, see PHP Date Formatting

End Date String

20-characters


endTime

EndDateUtc

Required

Must be in the format of Y-m-d\TH:i:s

e.g. 2000-05-30T14:38:22

For formatting help, see PHP Date Formatting

permitNo String 50-characters

permitNo

Optional The permit identifier or unique receipt ID
Ticket Number String 50-characters

TicketNumber

Optional The ticket identifier or unique receipt ID
zone String 200-characters

zone

ParkingZoneName

Optional

The localized parking area identifier. This should match an explicit string name inside the system. If the zone does not match a zone in our system, it will be a disconnected record and may not report properly.

promoCode String 50-characters

promoCode

Optional

Alphanumeric validation string detailing applied customer discounts, validation codes, or free parking promotional campaigns (e.g., HotSpot promo keys).

API Server Responses

Successful Response

Upon successfully accepting and writing a record to the database, the server transmits an HTTP status code 200 OK along with a tracking object.

Successful Response

The response will be a json object. Content-Type: application/json

JSON

{
    "status": "success",
    "reference_id": "1a9b5375-cb75-4c71-9939-eeae550b09ac",
    "InternalReferenceID": "1a9b5375-cb75-4c71-9939-eeae550b09ac"
}

Best Practices and Considerations

Permits API

Push API: Permit Update

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

The OPSCOM Controller provides a simple JSON based API to integrate with. Clients use this API to directly feed paid permit details into OPSCOM from other systems such as Parking Apps.  

Make sure you set the HTTP Content-Type header to be application/json.

Making API Requests

Raw Request:

POST /api/OC-TOMA/v1/permits/update HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
    "referenceID": "PREVIOUS-REFERENCE-ID",
    "plate": "PL8RDR",
    "Amount": "14.50",
    "currency": "CAD",
    "endTime": "2018-07-02T09:30:00"
}

JavaScript Request:

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN",
    "referenceID""PREVIOUS-REFERENCE-ID",
    "plate""PL8RDR",
    "Amount""14.50",
    "currency""CAD",
    "endTime""2018-07-02T09:30:00"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute Type Limits Possible Names Description
apiToken String

50-character alphanumeric including dashes

apiToken (Required) Your supplied API Token.

Reference ID

String 50-character alphanumeric including dashes

referenceid

referenceID

reference_id

(Required) This value is supplied to when the permit push api is successful.

e.g. 1a9b5375-cb75-4c71-9939-eeae550b09ac

End Date String

20-characters

Y-m-d\TH:i:s format.

endTime

EndDateUtc

(Optional) Must be in the format of Y-m-d\TH:i:s

e.g. 2000-05-30T14:38:22

For formatting help, see PHP Date Formatting

License Plate String 25-characters

plate

LicencePlate

(Optional) The plate of the vehicle.
Amount String 9-character decimal

amount

Amount

(Optional) Transaction amount This must contain at least 3 digits, two of which are penny values.

The minimum allowable value is $0.01, and the maximum allowable value is $999999.99.

Currency String 10-characters

currency

CurrencyID

(Optional) CAD, USD

Successful Response

The response will be a json object. The same reference id will be returned.

Content-Type: application/json

{
    "status""success",
    "reference_id""1a9b5375-cb75-4c71-9939-eeae550b09ac",
    "InternalReferenceID""1a9b5375-cb75-4c71-9939-eeae550b09ac"
}

Push API: Vehicle Create

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

The OPSCOM Controller provides a simple JSON based API to integrate with. Clients use this API to directly feed vehicles into OPSCOM from other systems.  

Make sure you set the HTTP Content-Type header to be application/json.

Making API Requests

Raw Request:

POST /api/OC_TOMA/v1/vehicles/push HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
    "plate": "PL8RDR",
    "plateType": "Motorcycle",
    "prov": "MA",
    "make": "8",
    "type": "3",
    "colour": "red",
    "year": "2011",
    "vin": "8GKS1AKC7FR518845"
}

JavaScript Request:

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN",
    "plate""PL8RDR",
    "plateType""Motorcycle",
    "prov""MA",
    "make""kia",
    "type""commercial",
    "colour""red",
    "year""2021",
    "vin""8GKS1AKC7FR518845"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute Type Limits Possible Names Description
apiToken String

50-character alphanumeric including dashes.

apiToken (Required) Your supplied API Token.
plate String 50-character alphanumeric.

plate


(Required) The license plate.

plateTypeID String

The ID of the VechiclePlateType record.

plateTypeID (One of plateTypeID or plateType is required) Your supplied VehiclePlateType identifier.
plateType String

50-character alphanumeric including dashes.

plateType (One of plateTypeID or plateType is required) The name of the plate type.
provID String

The ID of the state/province.

provID (One of provID or prov is required) Your supplied state or province identifier.
prov String

50-character alphanumeric including dashes

prov (One of provID or prov is required) The full name of the state/province or the corresponding postal abbreviation.
makeID String

The ID of the vehicle make.

makeID (Optional) Your supplied vehicle make identifier.
make String 50-character alphanumeric including dashes

make

(Optional) The name of the vehicle manufacturer. 
typeID String

The ID of the vehicle type.

typeID (Optional) Your supplied vehicle type identifier.
type String

50-character alphanumeric including dashes

type (Optional) The name of the type of vehicle that you provided.
colourID String The ID of the vehicle colour. colourID (Optional) Your supplied vehicle colour identifier.

colour

String

50-character alphanumeric including dashes

colour

(Optional) The name of a colour that you have provided..

year String

4 digit year.

year

(Optional) The model year.

vin String 25-characters

vin

(Optional) The vehicle identification number.

Successful Response

The response will be a json object. 

Content-Type: application/json

{
    "status""success",
    "vehicle_id_id""158",
    "warnings":["The vehicle colour name was too long and has been truncated."]
}

Pull API: UserType

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

The OPSCOM Controller provides a simple JSON based API to integrate with. Clients use this API to obtain a list of the current profile user types in their system.

Make sure you set the HTTP Content-Type header to be application/json.

Making API Requests

Raw Request:

POST /api/OC_TOMA/v1/profiles/types/list HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
}

JavaScript Request:

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute Type Limits Possible Names Description
apiToken String

50-character alphanumeric including dashes.

apiToken (Required) Your supplied API Token.

Successful Response

The response will be a json object. 

Content-Type: application/json

{
    "status""success",
    "user_types": [
        {
            "id""1",
            "type_name""Full Time Student",
            "ext_info""Student"
        },
        {
            "id""6",
            "type_name""Demo",
            "ext_info""Public"
        },
        {
            "id""7",
            "type_name""Full Time Staff",
            "ext_info""Staff"
        },
        {
            "id""8",
            "type_name""Part Time Staff",
            "ext_info""Staff"
        },
        {
            "id""9",
            "type_name""Part Time Student",
            "ext_info""Student"
        },
        {
            "id""10",
            "type_name""Exchange Student",
            "ext_info""Student"
        },
        {
            "id""11",
            "type_name""Athletics Member",
            "ext_info""Athletics"
        },
        {
            "id""12",
            "type_name""Complimentary",
            "ext_info""Public"
        },
        {
            "id""13",
            "type_name""Daily Reserved",
            "ext_info""Public"
        }
    ]
}

Push API: User Create/Update

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

The OPSCOM Controller provides a simple JSON based API to integrate with. Clients use this API to push to OPSCOM new users and update existing users directly from another system. For example, you may wish to push Student and Staff information from Banner directly to OPSCOM.

Make sure you set the HTTP Content-Type header to be application/json.

Making API Requests

Raw Request:

POST /api/OC_TOMA/v1/profiles/push HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
    "unique_id": "tester23",
    "login_source": "OPSCOM",
    "first_name":"firstname",
    "last_name":"lastname",
    "user_name":"username",
    "email":"test@test.com",
    "street":"123 Main Street, 123 Main Street,123 Main Street,123 Main Street,123 Main Street,123 Main Street",
    "city":"Everywhere",
    "province":"bc",
    "state":"NY",
    "postal_code":"HOHOHO",
    "zip":"12345-1212",
    "street2":"123 General Street",
    "city2":"Somewhere",
    "province2":"AB",
    "state2":"MA",
    "postal_code2":"A9A9A9",
    "zip2":"54321-1212",
    "phone_cell":"613-555-1212",
    "user_type_id":"6",
    "employ_no":"employee number: default",
    "employee_phone":"emp ph. klondike 555",
    "student_no":"SN 543209854",
    "student_phone":"999",
    "driver_licence_num":"QC 99999999",
    "driver_license_num":"NYNY",
    "date_of_birth":"1901-01-31",
    "locker_user_type_id":"3",
    "driver_licence_prov":"BC",
    "driver_license_state":"CA"
}

JavaScript Request:

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN",
    "unique_id""tester23",
    "login_source""OPSCOM",
    "first_name":"firstname",
    "last_name":"lastname",
    "user_name":"username",
    "email":"test@test.com",
    "street":"123 Main Street, 123 Main Street,123 Main Street,123 Main Street,123 Main Street,123 Main Street",
    "city":"Everywhere",
    "province":"bc",
    "state":"NY",
    "postal_code":"HOHOHO",
    "zip":"12345-1212",
    "street2":"123 General Street",
    "city2":"Somewhere",
    "province2":"AB",
    "state2":"MA",
    "postal_code2":"A9A9A9",
    "zip2":"54321-1212",
    "phone_cell":"613-555-1212",
    "user_type_id":"6",
    "employ_no":"employee number: default",
    "employee_phone":"emp ph. klondike 555",
    "student_no":"SN 543209854",
    "student_phone":"999",
    "driver_licence_num":"QC 99999999",
    "driver_license_num":"NYNY",
    "date_of_birth":"1901-01-31",
    "locker_user_type_id":"3",
    "driver_licence_prov":"BC",
    "driver_license_state":"CA"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute Type Limits Possible Names Description
apiToken String

50-character alphanumeric including dashes.

apiToken (Required) Your supplied API Token.
Unique ID String 50-character alphanumeric including dashes. unique_id (Required) An unique identification number of the user.
Login Source String 20-character alphanumeric including dashes. login_source (Required) Your supplied login source.
First Name String 50-character alphanumeric including dashes. first_name (Optional)  User's first name.
Last Name String 50-character alphanumeric including dashes. last_name (Optional) User's last name.
User Name String 50-character alphanumeric including dashes. user_name (Optional) Unique username.
Email String 100-character alphanumeric including dashes. email (Optional) Valid email address .
Street - address 1 String
street (Optional) User's primary street number and name.
City - address 1 String 50-character alphanumeric including dashes. city (Optional) User's primary city name.
Province - address 1 String 2-character postal abbreviation eg. "MA"

province,

state

(Optional)  User's primary province or state.
Postal Code - address 1 String 20-character alphanumeric including dashes.

postal_code,

zip

(Optional) User's primary postal code or zip.
Street - address 2 String 20-character alphanumeric including dashes. street2 (Optional) User's alternate street number and name.
City - address 2 String 50-character alphanumeric including dashes. city2 (Optional) User's alternate city name.
Province - address 2 String 2-character postal abbreviation eg. "MA"

province2,

state2

(Optional) User's alternate province or state.
Postal_Code - address 2 String 20-character alphanumeric including dashes.

postal_code2,

zip2

(Optional) User's alternate postal code or zip.
Cell phone number String 20-character alphanumeric including dashes. phone_cell (Optional) User's cell phone number
User Type ID String Id number of UserType user_type_id (Optional) A reference number to the type of user.
Employee Number String 50-character alphanumeric including dashes. employ_no (Optional) User's employee number. 
Employee phone number String 50-character alphanumeric including dashes. employee_phone (Optional) User's employee phone number.
Student number String 50-character alphanumeric including dashes. student_no (Optional) User's student number.
Student phone number String 50-character alphanumeric including dashes. student_phone (Optional) User's student phone number.
Driver licence number String 255-character alphanumeric including dashes.

driver_licence_num,

driver_license_num

(Optional) User's driver's licence number or driver's license number.
Date of Birth String 10-character date in format 'yyyy-mm-dd' date_of_birth (Optional) User's date of birth in format "YYYY-MM-DD.
Locker User Type ID String Id number of LockerUserType locker_user_type_id (Optional) A reference the the user's locker type id of the user.
Driver's licence province String 2-character postal abbreviation eg. "MA"

driver_licence_prov,

driver_license_state

(Optional) The province or state of the user's driver's licence.

Successful Response

The response will be a json object. 

Content-Type: application/json

{
    "status""success",
    "reference_id": 44
}

Pull API: Overdue Violations

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

The OPSCOM Controller provides a simple JSON based API to integrate with.

Clients use this API to export a list of the currently overdue violations, which are then marked as having been sent to collections.

Make sure you set the HTTP Content-Type header to be application/json.

Information

When accessed, this API will send all overdue violations that have not been sent to collections yet in a JSON object. It will also mark them as having been sent to collections, so subsequent calls to the API will not get the same information more than once.

This is a POST request. Data is being posted to the server.

POST /api/{client}/v1/violations/send_overdue_to_collections

Sample Request - All Params

/api/OC_TOMA/v1/violations/send_overdue_to_collections

Making API Requests

Raw Request:

POST /api/OC_TOMA/v1/violations/send_overdue_to_collections HTTP/1.1
Host: controller.operationscommander.io
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "apiToken": "YOUR-API-TOKEN",
}

JavaScript Request:

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "apiToken""YOUR-API-TOKEN"
}
request.send(JSON.stringify(body));

Request Object Attributes

Attribute Type Limits Possible Names Description
apiToken String

50-character alphanumeric including dashes.

apiToken (Required) Your supplied API Token.

Successful Response

The response will be a JSON object.

Content-Type: application/json

{
  "records": [
    {
      "ViolationID": 9,
      "SemPermitID": 0,
      "Ticket""1-100013",
      "VehicleID": 8,
      "Spoiled": 0,
      "TicketType": 2,
      "Issued""2016-05-03T20:00:00.000000Z",
      "convNotice"null,
      "Due""2016-05-23T20:00:00.000000Z",
      "ViolationTypeID": -1,
      "Fine": 50,
      "AdjustedFine": 0,
      "Towing": 0,
      "taxAmount""0.0000",
      "Writer": 8,
      "LocationID": 6,
      "Comment"null,
      "TicketAppeal"null,
      "appealType": 0,
      "appealFormat"null,
      "AccessAdminID": 7,
      "ActionedPer"null,
      "Created""2020-10-15T20:13:24.000000Z",
      "AppealUserID": 0,
      "AppealProcessDate"null,
      "AppealAdminID": 0,
      "AppealComment"null,
      "AppealAdminComment"null,
      "AutoNotice": 2,
      "ProcessedByCollection"null,
      "SentToCollections"null,
      "PrivateComments"null,
      "DriveAway": 0,
      "UUID""d9a1c8bb-4ed1-411e-91b1-0b63ba52e04d",
      "VioNotice"null,
      "latitude"null,
      "longitude"null,
      "Warning"null,
      "userid"null,
      "incidentID"null,
      "failToIdentify"null,
      "pin"null,
      "duplicate"null,
      "AdjustmentReason"null,
      "user"null,
      "vehicle": {
        "VehicleID": 8,
        "Active": 1,
        "lastUpdate""2020-10-15T20:13:03.000000Z",
        "Plate""AJNR123",
        "PlateTypeID": 4,
        "ProvID": 9,
        "MakeID": 13,
        "TypeID": 5,
        "ColourID": 14,
        "Year": 2006,
        "TotalVio": 0,
        "TotalUnpaid": 0,
        "TotalWarning": 0,
        "created""2020-10-15T20:13:03.000000Z",
        "externallookupdate"null,
        "externallookupRequestID"null,
        "modified""2022-03-16T21:36:09.000000Z",
        "vehicleAlert"null,
        "vin"null,
        "drivers": [
          {
            "UserID": 73,
            "enabled"null,
            "salutation""Dr.",
            "firstName""stephen_14Oct_1114",
            "middleName"null,
            "lastName""stephen_14Oct_1114",
            "username""stephen_14Oct_1114",
            "email""stephen_14Oct_1114@test",
            "street""1234 Main Street",
            "city""Ottawa",
            "prov": 9,
            "postal""H0H0H0",
            "street2"null,
            "city2"null,
            "prov2"null,
            "postal2"null,
            "phonecell""6135551212",
            "status": 1,
            "UserTypeID": 7,
            "employNo""staff12341115",
            "deptNameID"null,
            "ePhone"null,
            "staffFacultyFlag": 0,
            "studentNo"null,
            "sPhone"null,
            "sPhone2"null,
            "lastUpdated""2022-08-29T21:31:12.000000Z",
            "created""2020-10-15T20:12:57.000000Z",
            "privateComment"null,
            "publicComment"null,
            "DLNum""DL 123451114",
            "DOB""2020-10-14T04:00:00.000000Z",
            "StaffMailPermit": 0,
            "ExtendedID"null,
            "UserUUID""42c5d253-2f06-4ab6-9090-969333c25da6",
            "CampusBox"null,
            "newEmail"null,
            "ReadOnlyUserID"null,
            "studentNo_int"null,
            "employNo_int"null,
            "StuCampusLocation"null,
            "EmpCampusLocation"null,
            "MailPermitTo""Permanent Mailing Address",
            "isCloudAccount"null,
            "lastSelfUpdated"null,
            "emailConsent"null,
            "T2P_reminders"null,
            "reminderTime"null,
            "lockerUserTypeID"null,
            "encid""A063AA9AC458DA5581FC777ADC9875FF",
            "preferredname"null,
            "plateAlert": 0,
            "peopleAlert": 0,
            "salt""85cf3dbb-54de-48e3-a2d1-0b312dd4cea8",
            "forcePasswordChange": 1,
            "lastpasswordchange"null,
            "DLprov": 66,
            "loginSource""OPSCOM",
            "company_id"null,
            "taxexemption"null,
            "company_manager"null,
            "receives_invoice"null,
            "account_number"null,
            "company_bill_recipient"null,
            "kais_employer"null,
            "kais_building"null,
            "kais_supervisor_name"null,
            "kais_supervisor_title"null,
            "register_token"null,
            "api_token"null,
            "modified""2022-08-29T21:36:24.000000Z",
            "bambora_customer_code"null,
            "language""fr",
            "preferred_communication_method"null,
            "laravel_through_key": 8
          }
        ],
        "make": {
          "MakeID": 13,
          "MakeName""Chevrolet",
          "modified""2020-10-15T20:13:11.000000Z"
        },
        "colour": {
          "ColourID": 14,
          "ColourName""Red",
          "ColourKey"null,
          "modified""2020-10-15T20:13:08.000000Z"
        },
        "vehicle_type": {
          "TypeID": 5,
          "TypeName""Compact",
          "modified""2020-10-15T20:13:13.000000Z"
        },
        "plate_type": {
          "TypeID": 4,
          "TypeName""Passenger",
          "modified""2022-04-15T20:58:56.000000Z",
          "typeCode""passenger"
        },
        "province": {
          "ProvID": 9,
          "ProvName""Ontario",
          "Country": 1,
          "ProvCode""ON",
          "modified""2022-08-30T21:54:10.000000Z",
          "payments": 1
        }
      },
      "location": {
        "LocationID": 6,
        "LocationName""Downtown Business District",
        "WriterVisible": 1,
        "GisNo": 0,
        "modified""2020-10-15T20:04:19.000000Z"
      },
      "details": [
        {
          "ViolationsDetailID": 10,
          "ViolationID": 9,
          "Ticket""1-100013",
          "ViolationTypeID": 9,
          "LocationID": 6,
          "offenceFine": 50,
          "discountFlag": 1,
          "discountAmount": 10,
          "discountHours": 168,
          "created""2020-10-15T20:13:33.000000Z",
          "type": {
            "ViolationTypeID": 9,
            "ViolationDescr""Parked in Loading Zone",
            "DefaultCost": 50,
            "created""2020-10-15T20:13:41.000000Z",
            "discountFlag"true,
            "discountAmount": 10,
            "discountHours": 168,
            "adminOnly"false,
            "violationkey"null,
            "modified""2020-10-15T20:13:41.000000Z",
            "category_id": 1,
            "adjustable"false,
            "bylawcode""BL-78"
          }
        }
      ],
      "attachments": [
        {
          "attachID": 1,
          "storageLocation""oc_tomahawk/VIOLATIONS/2022/08/23/index-debf76b6.png",
          "attachName""index-debf76b6",
          "attachExt""png",
          "attachMime""image/png",
          "relatedType""VIOLATIONS",
          "relatedID": 9,
          "relatedNote""1-100013",
          "created""2022-08-23T18:48:36.000000Z",
          "archived"null,
          "uniqueid""70756a09-550e-433d-b6f4-75b0bfdcef60"
        },
        {
          "attachID": 2,
          "storageLocation""oc_tomahawk/VIOLATIONS/2022/08/23/index-b11529e8.png",
          "attachName""index-b11529e8",
          "attachExt""png",
          "attachMime""image/png",
          "relatedType""VIOLATIONS",
          "relatedID": 9,
          "relatedNote""1-100013",
          "created""2022-08-23T20:55:23.000000Z",
          "archived"null,
          "uniqueid""079541cf-302e-4c42-a2cf-38665643d364"
        }
      ],
      "category": {
        "TicketTypeID": 2,
        "TicketTypeName""Municipal",
        "HandHeldVisible": 0,
        "modified""2020-10-15T20:12:51.000000Z",
        "archived"null,
        "appliesTo": 1,
        "enableFailToIdentify": 0
      }
    }
  ],
  "state": {
    "version""2022.5.hawksbill.0-rc",
    "csrf_token""xSc9UppEG8iMXFu606Z6sfemODRyHuoyvKYT0vs6"
  }
}

Pull API: Plate Validation

API access is a paid feature and must be granted by OPSCOM. Email your Account Executive to negotiate access. 

Use this API to obtain details related to a plate.  Plate details include permits, alerts and DNTT status.

Make sure you set the HTTP Content-Type header to be application/json.

Making API Requests

Raw Request

POST /api/v1/validate/plate HTTP/1.1
Host: service.OPSCOM.com
Accept: application/json
Content-Type: application/json
Cache-Control: no-cache
 
{
    "api_token": "YOUR-API-TOKEN",
    "client": "<client ID>",
    "plate": "<plate to validate>"
}

JavaScript Request

var request = new XMLHttpRequest();
 
 
request.setRequestHeader('Content-Type''application/json');
request.setRequestHeader('Accept''application/json');
 
request.onreadystatechange = function () {
  if (this.readyState === 4) {
    console.log('Status:'this.status);
    console.log('Headers:'this.getAllResponseHeaders());
    console.log('Body:'this.responseText);
  }
};
 
 
var body = {
    "api_token""YOUR-API-TOKEN",
    "client""<client ID>",
    "plate""<plate to validate>"
}
request.send(JSON.stringify(body));

Request Object Attributes

api_token String

50-character alphanumeric including dashes.


(Required) Your supplied API Token.
client String client identifier
Required
plate String vehicle plate
Required

Response Values

error integer error code 0=success
data JSON bundle returned data
data.response String

{permits}\n\nALARM: {alarm}\n\n DNTT: {DNTT}

empty if no data
data.plate String plate validated
data.responseJSON JSON bundle response in JSON
data.responseJSON.permits Array

array of permits 

  • type, (lot) shortName, expires
all elements: String
data.responseJSON.dntt Array

array of DNTT (do not ticket tow) results

  • notes, location, start, end
all elements: String
data.responseJSON.alarm String alarm associated with plate or linked driver
message String system error message

Successful Response

The response will be a json object. 

Content-Type: application/json

/*
    The below response is a merged example of different fields that may be in the response.
    - 'type' may be: standard, temp, Validated, T2, HotSpot, or any other "origin"
*/
 
/* sample response with many included details */
{
    "error": 0,
    "data": {
 
        /* 'response' is a string concatenated list of all values carriage return delineated */
        "response""standard: BIKE\n Expires: 2025-04-30 23:59:59\nstandard: MOTO-S\n Expires: 2025-04-30 23:59:59\n\nALARM: Wanted to talk with.\n\nDNTT: Main Campus\n2024-11-15 00:00:00-2024-11-15 23:59:00 \nCLEAR FOR ANY PAY AREA\n\n",
 
        "plate""ABC123",
 
        "responseJSON": {
            "permits": [
                {
                    "expires""2025-04-30 23:59:59",
                    "type""standard",
                    "shortName""BIKE"
                },
                {
                    "expires""2025-04-30 23:59:59",
                    "type""standard",
                    "shortName""MOTO-S"
                }
            ],
 
            /* like 'permits', 'dntt' (do not ticket or tow) could be an array of values */
            "dntt": [{
                "notes""CLEAR FOR ANY PAY AREA",
                "start""2024-11-15 00:00:00",
                "location""Main Campus",
                "end""2024-11-15 23:59:00"
            }],
 
            "alarm":"Wanted to talk with."
        },
    }
    "message"""
}

Response Samples

Any response listed below could be merged with any other.  This is a list of possible responses to demonstrate responses with data.

/* No data */
{
    "error": 0,
    "data": {
        "response""",
        "plate""ABC123",
        "responseJSON": {}
    },
    "message"""
}
 
/* standard (temp, Validated, T2, HotSpot, ...) */
{
    "error": 0,
    "data": {
            "response""standard: LOT3\n Expires: 2025-04-30 23:59:59\nstandard: MOTO-S\n Expires: 2025-04-30 23:59:59\n\n",
            "plate""ABC890",
            "responseJSON": {
                "permits": [
                    {
                        "expires""2025-04-30 23:59:59",
                        "type""standard",
                        "shortName""BIKE"
                    },
                    {
                        "expires""2025-04-30 23:59:59",
                        "type""standard",
                        "shortName""MOTO-S"
                    }
            ],
        }
    },
    "message"""
}
 
/* plate with alarm */
{
    "error": 0,
    "data": {
            "response""ALARM: 15-AS123 Lex Luthor (08 JUL 84) wanted by OPS.\r\n\r\n*** Violence / Weapons ***\n\n",
            "plate""ABC456",
            "responseJSON": {
                "alarm""15-AS123 Lex Luthor (08 JUL 84) wanted by OPS.\r\n\r\n*** Violence / Weapons ***"
        }
    },
    "message"""
}
 
/* DNTT: do not ticket or tow */
{
    "error": 0,
    "data": {
        "response""DNTT: Lot 6\n2024-10-23 00:00:00-2025-04-30 23:59:00 \nHertz truck has permission to park overnight in lot 6. Rental for We-Move-It Services\n\n",
        "plate""DEF123",
        "responseJSON": {
            "permits": [],
            "dntt": [
                {
                    "notes""Hertz truck has permission to park overnight in lot 6. Rental for We-Move-It Services",
                    "start""2024-10-23 00:00:00",
                    "location""Lot 6",
                    "end""2025-04-30 23:59:00"
                }
            ],
            "active""1"
        }
    },
    "message"""
}

Lot Value API

The Lot Value API provides administrators with a programmatic version of the existing Lot Value Report. Its primary purpose is to retrieve real-time parking lot occupancy, valuation, and capacity data directly from the OPSCOM Controller, allowing organizations to independently ingest this information into their own custom data dashboards or third-party reporting tools.

Setup and Configuration

Before querying the endpoint, A Tomahawk Support agent must generate an authentication token with the correct structural permissions assigned. Once this token is generated for you, it will be sent securely to you, and you can use this API key in the body of a get request, sent to this endpoint:

https://controller.preview.operationscommander.io/api/[YOUR CLIENT ID]/v1/permits/lot-values

This is how the body should be formatted to receive lot values in return;

{
    "apiToken": "0d2bef1a-4819-4c6a-b552-1b9e3d936333"
}

No other information is required in the body, this get request will return a list of the values of each lot in order of lot ID.

Using this Feature

The endpoint mimics the data structure of the standard system report but delivers it as a structured payload for external integration.

Expected API Responses

A successful request returns a structured JSON payload containing real-time data for all configured parking lots. The output includes individual lot identifiers, total capacities, active permit counts, current vehicle volume calculations, and the monetary value assigned to the spaces.

If an unauthenticated key is passed into the request body, the server rejects the connection.

Here is an example of what the API will return:

[
    {
        "lot_type": "Y",
        "lot_name": "TU Residence",
        "default_cost": 525,
        "total_permits": 20,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "TU Residence Visitors",
        "default_cost": 11,
        "total_permits": 0,
        "rented_permits": 0,
        "utilized_pct": null,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "S",
        "lot_name": "TU Semester East",
        "default_cost": 100,
        "total_permits": 21,
        "rented_permits": 17,
        "utilized_pct": 80.95,
        "amount_projected": 1700,
        "amount": 2897.8783,
        "tax_amount": 0,
        "tax_amount1": 144.89392,
        "tax_amount2": 231.83026,
        "total": 3274.6
    },
    {
        "lot_type": "M",
        "lot_name": "TU Semester Central",
        "default_cost": 125,
        "total_permits": 60,
        "rented_permits": 3,
        "utilized_pct": 5,
        "amount_projected": 375,
        "amount": 313.08447,
        "tax_amount": 0,
        "tax_amount1": 15.65422,
        "tax_amount2": 25.04676,
        "total": 353.79
    },
    {
        "lot_type": "Y",
        "lot_name": "TUSC Yearly Staff",
        "default_cost": 350,
        "total_permits": 10,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "Y",
        "lot_name": "TUSC Yearly Executive",
        "default_cost": 0,
        "total_permits": 10,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "TU Visitors",
        "default_cost": 11,
        "total_permits": 0,
        "rented_permits": 0,
        "utilized_pct": null,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "Veritas Communications - All Lots",
        "default_cost": 165,
        "total_permits": 28,
        "rented_permits": 2,
        "utilized_pct": 7.14,
        "amount_projected": 330,
        "amount": 330,
        "tax_amount": 0,
        "tax_amount1": 16.5,
        "tax_amount2": 26.4,
        "total": 372.9
    },
    {
        "lot_type": "M",
        "lot_name": "Veritas Communications - Complimentary",
        "default_cost": 0,
        "total_permits": 5,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "North Lot",
        "default_cost": 195,
        "total_permits": 0,
        "rented_permits": 0,
        "utilized_pct": null,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "Solus Tech Inc",
        "default_cost": 183,
        "total_permits": 15,
        "rented_permits": 2,
        "utilized_pct": 13.33,
        "amount_projected": 366,
        "amount": 366,
        "tax_amount": 0,
        "tax_amount1": 18.3,
        "tax_amount2": 29.28,
        "total": 413.58
    },
    {
        "lot_type": "M",
        "lot_name": "Recreation Complex",
        "default_cost": 0,
        "total_permits": 0,
        "rented_permits": 0,
        "utilized_pct": null,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "Main Street Parking",
        "default_cost": 200,
        "total_permits": 20,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "O",
        "lot_name": "Public Works",
        "default_cost": 0,
        "total_permits": 30,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "Mall Parking",
        "default_cost": 0,
        "total_permits": 0,
        "rented_permits": 0,
        "utilized_pct": null,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "Main Street Private Parking",
        "default_cost": 150,
        "total_permits": 200,
        "rented_permits": 0,
        "utilized_pct": 0,
        "amount_projected": 0,
        "amount": 0,
        "tax_amount": 0,
        "tax_amount1": 0,
        "tax_amount2": 0,
        "total": 0
    },
    {
        "lot_type": "M",
        "lot_name": "TU South Garage",
        "default_cost": 75,
        "total_permits": 3000,
        "rented_permits": 2,
        "utilized_pct": 0.07,
        "amount_projected": 150,
        "amount": 150,
        "tax_amount": 0,
        "tax_amount1": 7.5,
        "tax_amount2": 12,
        "total": 169.5
    }
]

Best Practices and Considerations