NAV Navbar
shell

Introduction

The SafetyAmp API can be used to access your data in the SafetyAmp platform. Currently, documentation is lagging behind the capabilities of the API - please contact our support team if the available documentation does not meet your needs.

The API is commonly used for adding and updating users/roles and dispatching audits.

Authentication

To authorize, use this code:

# Every request requires an Authorization header with your API token
curl "api_endpoint_here"
  -H "Authorization: Bearer your_api_token"

Make sure to replace your_api_token with your API key.

SafetyAmp uses API keys to allow access to the API. To request an API key, please e-mail our support team.

In most cases, your API key is tied to a user profile in the SafetyAmp account and you will likely create a new user to represent the api user.

SafetyAmp expects for the API key to be included in all API requests to the server in a header that looks like the following:

Authorization: Bearer api_key

Making Requests

Apart from including the Authorization header, there are additional headers that are required for every API request.

Required HTTP Headers

Name Example Value Description
Authorization Bearer api_key This is used to authenticate your client
Fqdn your_subdomain.safetyamp.com This is the subdomain of the account your token is for
User-Agent YourOrg/1.0 Give your client a descriptive user agent that is unique to your organization
Accept application/json

Dates and Time

This API will respond with dates and times in the format YYYY-mm-dd H:i:s in the UTC timezone. Most requests expect a similarly formatted string also in UTC. Be sure to send datetime strings in UTC in this format.

Pagination Query Parameters

On list endpoints that support pagination, the following parameters are generally available.

Parameter Default Description
limit 25 The number of results per request
page 0 The number of pages to offset the results by

Rate Limit

To avoid receiving 429 - Too Many Requests error responses, ensure your client sends no more than 60 api calls per minute.

Filtering, Sorting, and Includes

List endpoints accept a standard request envelope for narrowing, ordering, and expanding the returned data. Each endpoint advertises which keys it supports for filtering, sorting, and including related resources.

# Filter utility bills to a single billing month, sort by period date, and
# include the related utility account and line items.
curl -G "https://api.safetyamp.com/api/utility_bills" \
  -H "Authorization: Bearer ..." \
  --data-urlencode 'filter_groups[0][filters][0][key]=billing_year' \
  --data-urlencode 'filter_groups[0][filters][0][operator]=eq' \
  --data-urlencode 'filter_groups[0][filters][0][value]=2025' \
  --data-urlencode 'filter_groups[0][filters][1][key]=billing_month' \
  --data-urlencode 'filter_groups[0][filters][1][operator]=eq' \
  --data-urlencode 'filter_groups[0][filters][1][value]=3' \
  --data-urlencode 'sort[0][key]=period_date' \
  --data-urlencode 'sort[0][direction]=desc' \
  --data-urlencode 'includes[]=utility_account' \
  --data-urlencode 'includes[]=line_items'

Filters

Filters are grouped under filter_groups[N][filters][M]. Each filter is an object with key, operator, and value. Filters within a group are combined with AND by default; pass filter_groups[N][or]=true to combine with OR instead.

Operator Description
eq Equal to
neq Not equal to
in Value matches any item in a comma-separated or array value
gt, gte Greater than (or equal)
lt, lte Less than (or equal)

Only the keys advertised by an endpoint may be used; unknown keys return 422 Unprocessable Entity.

Sorting

Sort entries are objects with key and optional direction (asc or desc, default asc):

sort[0][key]=period_date&sort[0][direction]=desc

Only the keys advertised by an endpoint are accepted.

Includes

includes[] expands related resources inline in the response. Endpoints document the include keys they support (e.g. utility_account, line_items.meter). Nested relations are addressed with dot notation.

Sites

Sites are physical locations of plants and facilities.

Get All Sites

curl "https://api.safetyamp.com/api/sites"
  -H "Authorization: Bearer ..."
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
  "data": [
      {
          "id": 1,
          "name": "Hybrid Plant - Austin, TX",
          "street": "111 Paradise Lane",
          "street2": null,
          "city": "Austin",
          "state": "TX",
          "zip_code": "11111",
          "country": "USA",
          "latitude": "",
          "longitude": "",
          "naics_code": null,
          "industry_description": "",
      },
      ...
  ]
}

This endpoint retrieves all sites.

HTTP Request

GET https://api.safetyamp.com/api/sites

Get a Specific Site

curl "GET https://api.safetyamp.com/api/sites/1"
  -H "Authorization: Bearer ..."

Refer to list endpoint for response

This endpoint retrieves a specific site.

HTTP Request

GET https://api.safetyamp.com/api/sites/<id>

URL Parameters

Parameter Description
id The id of the site to retrieve

Roles

SafetyAmp implements role based access control. Users are assigned to multiple roles and receive aggregate permissions from their combined roles.

Get All Roles

curl "https://api.safetyamp.com/api/roles"
  -H "Authorization: Bearer ..."
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 1,
            "name": "Plant Manager"
        },
        ...
    ]
}

This endpoint retrieves all roles.

HTTP Request

GET https://api.safetyamp.com/api/roles

Titles

SafetyAmp maintains a set of titles for your company. Users can be assigned one of these.

Get All Titles

curl "https://api.safetyamp.com/api/user_titles"
  -H "Authorization: Bearer ..."
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 1,
            "name": "Plant Assitant Manager"
        },
        ...
    ]
}

This endpoint retrieves all titles.

HTTP Request

GET https://api.safetyamp.com/api/user_titles

Users

Creating a User

This endpoint allows the creation of new users in your account.

curl -X POST "https://api.safetyamp.com/api/users" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d` {
        "first_name": "Jane",
        "middle_name": null,
        "last_name": "Doe",
        "nickname": null,
        "gender": "1",
        "email": "jane.doe@example.com",
        "date_of_birth": "1999-01-31",
        "street": "11 Paradise Ln",
        "street2": null,
        "city": "San Francisco",
        "state": "CA",
        "zip_code": "94131",
        "country":"US",
        "mobile_phone": "+11231231234",
        "home_phone": "+12342342345",
        "work_phone": "+13453453456",
        "pending":1,
        "system_access":1,
        "bypass_sso":0,
        "text_opt_out": 0,
        "text_opt_out":0,
        "timezone":"America/New_York",
        "roles":[{"id": 1}],
        "home_site_id": 1,
        "sites":[{"id": 1}],
        "current_title_id":1,
        "current_department_id":1,
        "current_supervisor_id":1
      }`

HTTP Request

POST https://api.safetyamp.com/api/users

Request Body

Parameter Description
first_name (Required) The first name of the user
last_name (Required) The last name of the user
email (Required) The email address of the user, must be unique, currently used as username
mobile_phone Integers only, used for SMS messaging if provided
system_access 1 if user can login to SafetyAmp, 0 if user cannot
pending Boolean, a user input with pending as true will not send Activation email on create
activated Set to 1 to activate user bypassing email validation
bypass_sso If SSO enabled for account, set to 1 to allow user to login without SSO
text_opt_out 1 if user does not wish to receive SMS on mobile number
timezone chosen from list of timezones in Object Reference
roles[] An array of objects containing id properties of the roles to assign to the user
home_site_id uses the id property of the site the user is primarily at. This will automatically be added to sites for site access
sites[] An array of objects containing the id property of the sites that user is allowed access to

Getting All Users

curl "https://api.safetyamp.com/api/users"
  -H "Authorization: Bearer ..."
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 1,
            "first_name": "Jane",
            "middle_name": null,
            "last_name": "Doe",
            "nickname": null,
            "date_of_birth": 1999-01-31,
            "owner": true,
            "email": "jane.doe@example.com",
            "work_phone": null,
            "home_phone": null,
            "mobile_phone": null,
            "avatar_location": null,
            "activated": 1,
            "gender": null,
            "street": "11 Paradise Ln",
            "city": "San Francisco",
            "state": "CA",
            "zip_code": "94131",
            "country": "USA",
            "street2": null,
            "text_opt_out": 0,
            "system_access": 1,
            "timezone": "America/Los_Angeles",
            "home_site_id": 1,
            "last_logged_in": "2019-10-25 21:40:22",
            "current_title": null,
            "deleted_at": null
        },
        ...
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/users

This endpoint supports pagination.

Getting a Specific User

curl "GET https://api.safetyamp.com/api/users/1"
  -H "Authorization: Bearer ..."

Refer to list endpoint for response

HTTP Request

GET https://api.safetyamp.com/api/users/<id>

URL Parameters

Parameter Description
id The id of the user to retrieve

Updating a User

curl -X PUT "https://api.safetyamp.com/api/users/<id>" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `{
    "first_name": "John",
    "last_name": "Doe",
    "email": "john.doe@example.com"
  }`

HTTP Request

PUT https://api.safetyamp.com/api/users/<id>

URL Parameters

first_name, last_name, and email are required fields on PUT calls. Refer to creating a user for list of additional parameters that can be updated. Only provided values will be updated.

Remove a User

Removing a user inactivates their user account and does not allow the user to access the SafetyAmp platform. The user data will be retained.

curl -X DELETE "https://api.safetyamp.com/api/users/<id>" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \

HTTP Request

DELETE https://api.safetyamp.com/api/users/<id>

URL Parameters

Parameter Description
id The id of the user to retrieve

SiteSense

SiteSense is SafetyAmp's energy management module. It tracks utility accounts (the relationship between a site and a utility provider), the meters attached to those accounts, and the bills (invoices) recorded against them. PDF copies of invoices are stored as attachments on the bill.

Permissions

SiteSense endpoints require one of two permissions:

Permission What it grants
InvoiceViewer Read-only access to utility accounts and bills. Account access is scoped to the user's accessible sites.
EnergyAdministrator Full read/write access to all SiteSense resources.

Endpoints that require EnergyAdministrator are noted on each section below.

Utility Types

Utility types are the categories of utility tracked by SiteSense (e.g. electricity, natural gas, water). The set of types is managed by SafetyAmp and cannot be created, updated, or deleted via the API.

List Utility Types

curl "https://api.safetyamp.com/api/utility_types" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 1,
            "name": "Electricity",
            "slug": "electricity",
            "unit_consumption": "kWh",
            "unit_demand": "kW"
        },
        {
            "id": 2,
            "name": "Natural Gas",
            "slug": "natural-gas",
            "unit_consumption": "therm",
            "unit_demand": null
        }
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/utility_types

This endpoint supports pagination.

Get a Utility Type

curl "https://api.safetyamp.com/api/utility_types/1" \
  -H "Authorization: Bearer ..."

Refer to list endpoint for response

HTTP Request

GET https://api.safetyamp.com/api/utility_types/<id>

URL Parameters

Parameter Description
id The id of the utility type to retrieve

Utility Accounts

A utility account represents a single account a site holds with a utility provider. Bills are recorded against accounts.

Requires InvoiceViewer or EnergyAdministrator. Users without EnergyAdministrator only see accounts at sites they have access to.

List Utility Accounts

curl "https://api.safetyamp.com/api/utility_accounts" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 12,
            "site_id": 1,
            "provider_ref": "ACCT-44123",
            "provider_name": "Austin Energy",
            "type": "delivery",
            "linked_to": null,
            "notes": null,
            "start_date": "2024-01-01",
            "is_excluded": false,
            "is_closed": false,
            "integration_type": null,
            "integration_ext_id": null,
            "integration_status": null,
            "last_missing_invoice_notification": null
        }
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/utility_accounts

Filter Keys

id, provider_id, provider_name, provider_ref, site_id, type_id, is_closed, is_excluded, integration_type, integration_status

Sort Keys

site, provider_name, provider_ref

Include Keys

site, meters, linked

Get a Utility Account

curl "https://api.safetyamp.com/api/utility_accounts/12" \
  -H "Authorization: Bearer ..."

Refer to list endpoint for response

HTTP Request

GET https://api.safetyamp.com/api/utility_accounts/<id>

URL Parameters

Parameter Description
id The id of the utility account to retrieve

Include Keys

site, meters, linked, default_line_items

Create a Utility Account

Requires EnergyAdministrator. Returns 409 Conflict if an account with the same site_id, provider_ref, and provider_name already exists.

curl -X POST "https://api.safetyamp.com/api/utility_accounts" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `{
        "site_id": 1,
        "provider_name": "Austin Energy",
        "provider_ref": "ACCT-44123",
        "type": "delivery",
        "start_date": "2024-01-01",
        "notes": null,
        "is_excluded": false,
        "is_closed": false
      }`

HTTP Request

POST https://api.safetyamp.com/api/utility_accounts

Request Body

Parameter Description
site_id (Required) The id of the site the account belongs to
provider_name (Required) Name of the utility provider, max 255 chars
start_date (Required) Date the account starts tracking bills, YYYY-MM-DD
provider_id Optional reference to a known utility provider record
provider_ref The provider's external account number, max 255 chars
type One of delivery, supply, general
linked_to The id of another active utility account this one is paired with
is_excluded Boolean, if true the account is excluded from energy model aggregations
is_closed Boolean, if true no new bills are expected on this account
integration_type arc to enable Arc integration. When set, the account is validated against Arc and tied to an Arc account id
meters An array of meter objects to create on the account. See "Sync Utility Account Meters" for the shape

Update a Utility Account

Requires EnergyAdministrator.

site_id cannot be changed after creation. If the account is configured with an integration, provider_ref and provider_name cannot be changed.

curl -X PATCH "https://api.safetyamp.com/api/utility_accounts/<id>" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `{
        "notes": "Switched to time-of-use rate in March",
        "is_closed": false
      }`

HTTP Request

PATCH https://api.safetyamp.com/api/utility_accounts/<id>

Request Body

All fields are optional. Same parameters as create, except site_id which is immutable. Also accepts default_line_items: an array of {utility_meter_id, type, desc} objects that fully replace the account's default line items used when creating new bills.

Delete a Utility Account

Requires EnergyAdministrator. Deleting an account also deletes any bills attached to it.

curl -X DELETE "https://api.safetyamp.com/api/utility_accounts/<id>" \
  -H "Authorization: Bearer ..."

HTTP Request

DELETE https://api.safetyamp.com/api/utility_accounts/<id>

Export Utility Account Bills

Requires EnergyAdministrator. Queues a background job that produces a CSV export of all bills at a site for a given year. The response is a JobStatus resource that can be polled to check progress and retrieve the resulting file.

curl -X POST "https://api.safetyamp.com/api/utility_accounts:export" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `{
        "site": 1,
        "year": 2025
      }`

HTTP Request

POST https://api.safetyamp.com/api/utility_accounts:export

Request Body

Parameter Description
site (Required) The id of the site to export bills for. Must have energy management enabled.
year (Required) The year to export, >= 2000

Utility Account Meters

Meters represent the individual measurement points on a utility account. A single account can have multiple meters (e.g. main panel and a sub-panel), each tied to a utility_type.

Requires EnergyAdministrator.

List Utility Account Meters

curl "https://api.safetyamp.com/api/utility_accounts/12/meters" \
  -H "Authorization: Bearer ..."

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 88,
            "name": "Main Electric Meter",
            "type_id": 1,
            "portfolio_mgr_id": null
        }
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/utility_accounts/<id>/meters

Sync Utility Account Meters

Requires EnergyAdministrator. This is a full sync: the request body must contain every meter that should exist on the account. Meters present on the account but absent from the payload are deleted. Meters with an id are updated; meters without one are created.

curl -X PUT "https://api.safetyamp.com/api/utility_accounts/12/meters" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `[
        { "id": 88, "name": "Main Electric Meter", "type_id": 1 },
        { "name": "Sub Panel A", "type_id": 1, "portfolio_mgr_id": "PM-1234" }
      ]`

HTTP Request

PUT https://api.safetyamp.com/api/utility_accounts/<id>/meters

Request Body

Each item in the array supports:

Parameter Description
id The id of an existing meter on this account. Omit to create a new meter.
name (Required when creating) The display name, max 255 chars
type_id (Required when creating) The id of a utility_type
portfolio_mgr_id Optional ENERGY STAR Portfolio Manager id, max 255 chars

Utility Bills

Utility bills (also called invoices) represent a single billing period on a utility account. Each bill carries one or more line items (usage, demand, or charges) and optionally one or more PDF attachments.

Requires InvoiceViewer or EnergyAdministrator. Users without EnergyAdministrator only see bills at sites they have access to.

List Utility Bills

curl "https://api.safetyamp.com/api/utility_bills" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json"

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 4801,
            "import_ref": null,
            "import_src": null,
            "utility_account_id": 12,
            "billing_year": 2025,
            "billing_month": 3,
            "period_date": "2025-02-15",
            "period_days": 30,
            "currency": "USD",
            "total_charges": 1842.55,
            "flags": [],
            "flags_silenced": false,
            "unavailable": false,
            "created_at": "2025-04-01 12:00:00",
            "updated_at": "2025-04-01 12:00:00"
        }
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/utility_bills

Filter Keys

id, utility_account_id, billing_year, billing_month

Sort Keys

period_date

Include Keys

site, attachments, utility_account, line_items, line_items.meter

Response Fields

Field Description
id The bill identifier
utility_account_id The id of the account this bill belongs to
billing_year Calendar year the bill covers
billing_month Calendar month the bill covers, 1-12
period_date First day of the billing period, YYYY-MM-DD
period_days Length of the billing period in days
currency One of USD, BSD, CAD, CRC, EUR, GBP, MXN, PAB, SEK
total_charges The sum of Charge line items in the bill's currency
flags An array of automated validation flags raised against this bill
flags_silenced Boolean, whether the flags were silenced by an admin
unavailable Boolean, true if the bill is recorded as known-missing for the period (placeholder; cannot have line items or attachments)
import_ref External id from the source system when the bill was imported. Cleared automatically if any non-flags_silenced field is updated.
import_src Name of the source system the bill was imported from

Get a Utility Bill

curl "https://api.safetyamp.com/api/utility_bills/4801" \
  -H "Authorization: Bearer ..."

Refer to list endpoint for response

HTTP Request

GET https://api.safetyamp.com/api/utility_bills/<id>

Include Keys

site, attachments, utility_account, utility_account.meters, line_items, line_items.meter, creator, updater

Create a Utility Bill

Requires EnergyAdministrator.

curl -X POST "https://api.safetyamp.com/api/utility_bills" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `{
        "utility_account_id": 12,
        "billing_year": 2025,
        "billing_month": 3,
        "period_date": "2025-02-15",
        "period_days": 30,
        "currency": "USD",
        "items": [
          { "type": 1, "meter_id": 88, "desc": "Usage",      "value": 12450 },
          { "type": 3, "meter_id": null, "desc": "Amount Due", "value": 1842.55 }
        ]
      }`

HTTP Request

POST https://api.safetyamp.com/api/utility_bills

Request Body

Parameter Description
utility_account_id (Required) The id of the account this bill belongs to
billing_year (Required) Calendar year, integer
billing_month (Required) Calendar month, integer 1-12
period_date (Required) First day of the billing period, YYYY-MM-DD
period_days (Required) Length of the billing period in days, integer ≥ 1
currency (Required) Three-letter currency code (see list endpoint)
items An array of line items. See "Sync Utility Bill Line Items" for the shape. Prohibited if unavailable is true.
flags_silenced Boolean, silences automated validation flags on creation
unavailable Boolean, mark the bill as known-missing. The bill cannot have line items or attachments.

A 422 is returned if the new bill overlaps an existing unavailable bill on the same account/period.

Update a Utility Bill

Requires EnergyAdministrator. The utility_account_id is immutable. Bills with unavailable=true cannot be updated.

curl -X PATCH "https://api.safetyamp.com/api/utility_bills/<id>" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `{
        "period_days": 31,
        "items": [
          { "id": 1, "type": 1, "meter_id": 88, "desc": "Usage", "value": 12500 }
        ]
      }`

HTTP Request

PATCH https://api.safetyamp.com/api/utility_bills/<id>

Request Body

All fields optional. Same parameters as create, except utility_account_id. If any field other than flags_silenced is updated, the bill's import_ref and import_src are cleared.

Delete a Utility Bill

Requires EnergyAdministrator. Also removes any PDF attachments on the bill.

curl -X DELETE "https://api.safetyamp.com/api/utility_bills/<id>" \
  -H "Authorization: Bearer ..."

HTTP Request

DELETE https://api.safetyamp.com/api/utility_bills/<id>

Utility Bill Line Items

A bill's line items break down its usage, demand, and charges, optionally tied to a specific meter.

List Utility Bill Line Items

curl "https://api.safetyamp.com/api/utility_bills/4801/line_items" \
  -H "Authorization: Bearer ..."

The above command returns JSON structured like this:

{
    "data": [
        { "id": 1, "meter_id": 88,   "desc": "Usage",      "type": 1, "value": 12450 },
        { "id": 2, "meter_id": 88,   "desc": "Peak Demand", "type": 2, "value": 42.1 },
        { "id": 3, "meter_id": null, "desc": "Amount Due",  "type": 3, "value": 1842.55 }
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/utility_bills/<id>/line_items

Line Item Types

Value Type Notes
1 Usage Quantity of the metered utility consumed (e.g. kWh)
2 Demand Peak demand for the period (e.g. kW)
3 Charge Monetary amount in the bill's currency

Line items without a meter_id (ad-hoc lines) must have type = 3 (Charge).

Sync Utility Bill Line Items

Requires EnergyAdministrator. A full sync: the array supplied replaces the bill's line items entirely.

curl -X PUT "https://api.safetyamp.com/api/utility_bills/4801/line_items" \
  -H "Authorization: Bearer ..." \
  -H "Content-Type: application/json" \
  -d `[
        { "id": 1, "type": 1, "meter_id": 88, "desc": "Usage",      "value": 12500 },
        { "type": 3,           "meter_id": null, "desc": "Late Fee",  "value": 25.00 }
      ]`

HTTP Request

PUT https://api.safetyamp.com/api/utility_bills/<id>/line_items

Request Body

Each item in the array supports:

Parameter Description
id The id of an existing line item. Omit to create a new one.
type (Required) One of 1 (Usage), 2 (Demand), 3 (Charge). Ad-hoc lines (meter_id=null) must use 3.
desc (Required) Description, max 255 chars
meter_id The id of a meter on this bill's account, or null for ad-hoc charges
value Numeric value, up to 4 decimal places

Utility Bill Attachments

PDFs (and other files) attached to a utility bill are exposed via short-lived signed URLs. To download an attachment:

  1. Call GET /api/utility_bills/<id>/attachments to list attachments on the bill, or GET /api/utility_bills/<id>/attachments/<attachment_id> for a single one.
  2. The response contains a temporary_url field. Issue a GET against that URL to download the file.
  3. The signed URL expires; re-request the attachment to obtain a fresh URL if needed.

List Utility Bill Attachments

curl "https://api.safetyamp.com/api/utility_bills/4801/attachments" \
  -H "Authorization: Bearer ..."

The above command returns JSON structured like this:

{
    "data": [
        {
            "id": 901,
            "file_name": "invoice-2025-03.pdf",
            "display_name": "March 2025 Invoice",
            "file_size": 184320,
            "mime_type": "application/pdf",
            "type": "default",
            "description": null,
            "private": false,
            "external_url": null,
            "temporary_url": "https://storage.safetyamp.com/...signed...",
            "created_at": "2025-04-01 12:00:00",
            "updated_at": "2025-04-01 12:00:00"
        }
    ]
}

HTTP Request

GET https://api.safetyamp.com/api/utility_bills/<id>/attachments

Get a Utility Bill Attachment

curl "https://api.safetyamp.com/api/utility_bills/4801/attachments/901" \
  -H "Authorization: Bearer ..."

Refer to list endpoint for response

HTTP Request

GET https://api.safetyamp.com/api/utility_bills/<id>/attachments/<attachment_id>

A 404 is returned if the attachment is not attached to the specified bill.

Upload a Utility Bill Attachment

Requires EnergyAdministrator. Bills marked unavailable=true cannot have attachments. Uploads are sent as multipart/form-data with a single attachment file field.

curl -X POST "https://api.safetyamp.com/api/utility_bills/4801/attachments" \
  -H "Authorization: Bearer ..." \
  -F "attachment=@invoice-2025-03.pdf"

Refer to list endpoint for response

HTTP Request

POST https://api.safetyamp.com/api/utility_bills/<id>/attachments

Request Body (multipart)

Parameter Description
attachment (Required) The file to upload

Delete a Utility Bill Attachment

Requires EnergyAdministrator.

curl -X DELETE "https://api.safetyamp.com/api/utility_bills/4801/attachments/901" \
  -H "Authorization: Bearer ..."

HTTP Request

DELETE https://api.safetyamp.com/api/utility_bills/<id>/attachments/<attachment_id>

A 404 is returned if the attachment is not attached to the specified bill.

Object Reference

User

{
    "data": {
        "id": "6Q4N8",
        "owner": false,
        "current_supervisor_id": null,
        "current_department_id": null,
        "email": "chris+conf-homer@safetyamp.com",
        "work_phone": "(345)345-3456",
        "home_phone": "(234)234-2345",
        "mobile_phone": "(123)123-1234",
        "avatar_location": null,
        "created_at": "2019-10-26 15:37:13",
        "created_by": "nRAzE",
        "updated_at": "2019-10-26 15:37:13",
        "updated_by": "nRAzE",
        "deleted_at": null,
        "deleted_by": null,
        "last_name": "Simpson",
        "date_of_birth": "1994-04-15",
        "gender": 1,
        "street": "street",
        "city": "city",
        "state": "state",
        "zip_code": "24477",
        "country": "US",
        "timezone": "America/New_York",
        "mailing_address_same_as_physical": 0,
        "mailing_street": "street2",
        "mailing_street2": "apt 22",
        "mailing_city": "city2",
        "mailing_state": "state2",
        "mailing_zip_code": "24472",
        "mailing_country": "US2",
        "current_title_id": null,
        "current_hire_date": null,
        "current_employee_status_id": null,
        "street2": "apt 20",
        "first_name": "Homer",
        "middle_name": null,
        "nickname": null,
        "activated": 0,
        "system_access": 1,
        "bypass_sso": 0,
        "text_opt_out": 0,
        "home_site_id": null,
        "last_logged_in": null,
        "remember_me": 0,
        "rate_limit": null,
        "constructed_permissions": [],
        "current_title": null,
        "preferences": null,
        "roles": [],
        "active_policies": [],
        "eligibility_events": [],
        "module_permissions": [],
        "current_department": null,
        "current_supervisor": null,
        "sites": [],
        "current_status": null,
        "permissions": []
    }
}

User Format

Key Type Description
email string The email address of the user (also, the username)
first_name string The first name of the user
middle_name string The middle name of the user
last_name string The last name of the user
owner boolean True if the user is the designated account owner
home_site_id int Id of users home site, controls record access
sites array[] Ids of sites user should have access to
roles array[] Ids of roles user should be given, controls system access
current_supervisor_id int The id of the users supervisor
current_department_id int The id of the users department
current_title_id int The id of the users title
mobile_phone string The users mobile phone number - SafetyAmp can send SMS
work_phone string The users work phone number
home_phone string The users home phone number
gender int 0 for male, 1 for female
street string User Address: Street address
street2 string User Address: Street address 2
city string User Address: City
state string User Address: State or Province
zip_code string User Address: Postal Code
country string User Address: Country
activated int 1 for activated, 0 for not activated
system_access int 1 if the user is allowed the ability to login
bypass_sso int If SSO enabled for account, set to 1 to allow user to login without SSO
text_opt_out int 1 if user does not wish to receive SMS on mobile number
last_logged_in string The time the user last used credentials to login, does not represent last activity in the system

Timezones

You can find a complete list of supported timezone strings (.e.g, America/New_York) by inspecting any timezone drop-down menu in the SafetyAmp web application.

Errors

The SafetyAmp API uses the following error codes:

Error Code Meaning
400 Bad Request -- Your request is invalid.
401 Unauthorized -- Your API key is wrong.
403 Forbidden -- You do not have access to the requested resource
404 Not Found -- The specified resource could not be found.
405 Method Not Allowed -- You tried to access an object with an invalid method.
422 Unprocessable Entity -- Your request is syntactically correct but one or more fields are incorrect.
429 Too Many Requests -- You've submitted more requests than the rate limit.
500 Internal Server Error -- We had a problem with our server. Try again later.
503 Service Unavailable -- We're temporarily offline for maintenance. Please try again later.