Skip to content
Docs

API reference

Usage

Read daily usage per device and totals per device, customer and month, or export them as CSV.

Usage comes from two sources. The provider is polled every hour (api basis) for day-to-day visibility; once a month the provider's records (cdr basis) arrive and become the figures invoices bill. Sizes are bytes; days and months are UTC.

The usage record object

One device's usage on one day, from one source.

Attributes

  • iduuidRequired

    Unique identifier.

  • customer_iduuid· nullable

    The device's customer when the usage was ingested.

  • device_iduuidRequired
  • downlink_bytesintegerRequired

    Bytes sent to the device.

  • inserted_attimestampRequired
  • provider_record_idstring· nullable

    The provider's own record id (CDR record_id), when it has one.

  • reseller_iduuid· nullable

    The device's reseller when the usage was ingested.

  • sourceenumRequired

    api (provider pull, operational) | cdr (monthly CDR import, billing).

    One ofapicdr

  • total_bytesintegerRequired

    Uplink plus downlink, as the provider reports it.

  • updated_attimestampRequired
  • uplink_bytesintegerRequired

    Bytes sent by the device.

  • usage_datedateRequired

    The UTC day the usage happened.

The usage record object
{
  "type": "usage_record",
  "id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
  "attributes": {
    "customer_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
    "device_id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
    "downlink_bytes": 48213,
    "inserted_at": "2026-10-12T14:03:21Z",
    "provider_record_id": null,
    "reseller_id": "a7d35c90-2e14-4f6b-8c03-5b9e1d4a2f67",
    "source": "api",
    "total_bytes": 48213,
    "updated_at": "2026-10-12T14:03:21Z",
    "uplink_bytes": 48213,
    "usage_date": "2026-10-01"
  }
}

The usage aggregate object

Totals for a device, a customer or your whole reseller, per day or per month. Cost fields appear only for Owners and Admins.

Attributes

  • iduuidRequired

    Unique identifier.

  • active_device_countintegerRequired

    Devices active in the period: daily, devices active on the day; monthly, distinct devices active on at least one day. Device rows: 1 or 0.

  • active_on_dayboolean· nullable

    Device-daily rows: whether the device was active on the day.

  • basisenumRequired

    api (provider pulls) | cdr (CDR import): the records it was computed from.

    One ofapicdr

  • customer_iduuid· nullable

    Customer scope (device and customer rows).

  • downlink_bytesintegerRequired
  • granularityenumRequired

    daily | monthly.

    One ofdailymonthly

  • iccidstring· nullable

    The device's ICCID (device rows only).

  • inserted_attimestampRequired
  • period_startdateRequired

    The day (daily) or the first of the month (monthly), UTC.

  • reseller_iduuid· nullable

    Reseller scope (device, customer and reseller rows).

  • retail_cost_centsinteger· nullable

    Retail cost in US cents. Reseller/customer Owner/Admin only; omitted otherwise.

  • scope_iduuid· nullable

    The device or organization id; null for platform rows.

  • scope_typeenumRequired

    device | customer | reseller | platform.

    One ofdevicecustomerresellerplatform

  • total_bytesintegerRequired
  • updated_attimestampRequired
  • uplink_bytesintegerRequired
  • wholesale_cost_centsinteger· nullable

    Wholesale cost in US cents. Reseller/platform Owner/Admin only; omitted otherwise.

The usage aggregate object
{
  "type": "usage_aggregate",
  "id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
  "attributes": {
    "active_device_count": 3,
    "active_on_day": false,
    "basis": "api",
    "customer_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
    "downlink_bytes": 48213,
    "granularity": "monthly",
    "iccid": "8999001234000020718",
    "inserted_at": "2026-10-12T14:03:21Z",
    "period_start": "2026-10-01",
    "reseller_id": "a7d35c90-2e14-4f6b-8c03-5b9e1d4a2f67",
    "retail_cost_cents": 1250,
    "scope_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
    "scope_type": "device",
    "total_bytes": 48213,
    "updated_at": "2026-10-12T14:03:21Z",
    "uplink_bytes": 48213,
    "wholesale_cost_cents": 1250
  }
}

Endpoints

List usage records

get/api/json/usage_records

Daily usage per device, newest day first. Filter by device_id, usage_date and source.

Who
Resellers and Customers
Roles
Owner, Admin, Staff

Query parameters

  • filter[<field>]object

    Narrows the list: filter[status]=active, or with an operator: filter[inserted_at][greater_than_or_equal]=2026-10-01T00:00:00Z. Operators: in, is_nil, greater_than, greater_than_or_equal, less_than, less_than_or_equal.

    One ofcustomer_iddevice_iddownlink_bytesidinserted_atprovider_record_idreseller_idsourcetotal_bytesupdated_atuplink_bytesusage_date

  • sortstring

    A field to sort by; prefix it with - for descending, e.g. sort=-inserted_at. Separate several with commas.

  • page[limit]integer

    Page size: 50 by default, at most 200.

  • page[after]string

    The cursor from links.next of the previous page. page[offset] works too.

  • page[count]boolean

    true adds the total number of matches in meta.page.total.

Request
curl https://api.houndsat.com/api/json/usage_records \
  -H "Authorization: Bearer $HOUNDSAT_TOKEN"
Response200 OK
{
  "data": [
    {
      "type": "usage_record",
      "id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
      "attributes": {
        "customer_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
        "device_id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
        "downlink_bytes": 48213,
        "inserted_at": "2026-10-12T14:03:21Z",
        "provider_record_id": null,
        "reseller_id": "a7d35c90-2e14-4f6b-8c03-5b9e1d4a2f67",
        "source": "api",
        "total_bytes": 48213,
        "updated_at": "2026-10-12T14:03:21Z",
        "uplink_bytes": 48213,
        "usage_date": "2026-10-01"
      }
    }
  ],
  "links": {
    "next": "/api/json/usage_records?page[after]=g2wAAAABbQAAACQ1ZjBj…"
  }
}

Get a usage record

get/api/json/usage_records/{id}

One usage record in your scope.

Who
Resellers and Customers
Roles
Owner, Admin, Staff

Path parameters

  • iduuidRequired

    The record's id.

Request
curl https://api.houndsat.com/api/json/usage_records/5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8 \
  -H "Authorization: Bearer $HOUNDSAT_TOKEN"
Response200 OK
{
  "data": {
    "type": "usage_record",
    "id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
    "attributes": {
      "customer_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
      "device_id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
      "downlink_bytes": 48213,
      "inserted_at": "2026-10-12T14:03:21Z",
      "provider_record_id": null,
      "reseller_id": "a7d35c90-2e14-4f6b-8c03-5b9e1d4a2f67",
      "source": "api",
      "total_bytes": 48213,
      "updated_at": "2026-10-12T14:03:21Z",
      "uplink_bytes": 48213,
      "usage_date": "2026-10-01"
    }
  }
}

List usage aggregates

get/api/json/usage_aggregates

Totals per period, newest first. Filter by granularity (daily, monthly), scope_type (device, customer, reseller), scope_id, period_start and basis.

Who
Resellers and Customers
Roles
Owner, Admin, Staff
  • Example: filter[granularity]=monthly&filter[scope_type]=customer gives each customer's monthly totals.

Query parameters

  • filter[<field>]object

    Narrows the list: filter[status]=active, or with an operator: filter[inserted_at][greater_than_or_equal]=2026-10-01T00:00:00Z. Operators: in, is_nil, greater_than, greater_than_or_equal, less_than, less_than_or_equal.

    One ofactive_device_countactive_on_daybasiscustomer_iddownlink_bytesgranularityiccididinserted_atperiod_startreseller_idscope_idscope_typetotal_bytesupdated_atuplink_bytes

  • sortstring

    A field to sort by; prefix it with - for descending, e.g. sort=-inserted_at. Separate several with commas.

  • page[limit]integer

    Page size: 50 by default, at most 200.

  • page[after]string

    The cursor from links.next of the previous page. page[offset] works too.

  • page[count]boolean

    true adds the total number of matches in meta.page.total.

Request
curl https://api.houndsat.com/api/json/usage_aggregates \
  -H "Authorization: Bearer $HOUNDSAT_TOKEN"
Response200 OK
{
  "data": [
    {
      "type": "usage_aggregate",
      "id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
      "attributes": {
        "active_device_count": 3,
        "active_on_day": false,
        "basis": "api",
        "customer_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
        "downlink_bytes": 48213,
        "granularity": "monthly",
        "iccid": "8999001234000020718",
        "inserted_at": "2026-10-12T14:03:21Z",
        "period_start": "2026-10-01",
        "reseller_id": "a7d35c90-2e14-4f6b-8c03-5b9e1d4a2f67",
        "retail_cost_cents": 1250,
        "scope_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
        "scope_type": "device",
        "total_bytes": 48213,
        "updated_at": "2026-10-12T14:03:21Z",
        "uplink_bytes": 48213,
        "wholesale_cost_cents": 1250
      }
    }
  ],
  "links": {
    "next": "/api/json/usage_aggregates?page[after]=g2wAAAABbQAAACQ1ZjBj…"
  }
}

Get a usage aggregate

get/api/json/usage_aggregates/{id}

One usage aggregate in your scope.

Who
Resellers and Customers
Roles
Owner, Admin, Staff

Path parameters

  • iduuidRequired

    The record's id.

Request
curl https://api.houndsat.com/api/json/usage_aggregates/5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8 \
  -H "Authorization: Bearer $HOUNDSAT_TOKEN"
Response200 OK
{
  "data": {
    "type": "usage_aggregate",
    "id": "5f0c2b7e-8d41-4a96-b3e2-91c7d0a4e6f8",
    "attributes": {
      "active_device_count": 3,
      "active_on_day": false,
      "basis": "api",
      "customer_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
      "downlink_bytes": 48213,
      "granularity": "monthly",
      "iccid": "8999001234000020718",
      "inserted_at": "2026-10-12T14:03:21Z",
      "period_start": "2026-10-01",
      "reseller_id": "a7d35c90-2e14-4f6b-8c03-5b9e1d4a2f67",
      "retail_cost_cents": 1250,
      "scope_id": "c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14",
      "scope_type": "device",
      "total_bytes": 48213,
      "updated_at": "2026-10-12T14:03:21Z",
      "uplink_bytes": 48213,
      "wholesale_cost_cents": 1250
    }
  }
}

List closed months

get/api/json/usage_months

Past months whose provider records have all arrived. For these months the cdr basis figures are final and are what invoices bill.

Who
Resellers and Customers
Roles
Owner, Admin, Staff
Request
curl https://api.houndsat.com/api/json/usage_months \
  -H "Authorization: Bearer $HOUNDSAT_TOKEN"
Response200 OK
[
  {
    "closed_at": "2026-10-12T14:03:21Z",
    "month": "2026-10-01"
  }
]

Export usage as CSV

get/api/exports/usage.csv

Usage aggregates as a CSV file, one row per scope and period. Staff never get the cost columns. At most 366 days or 120 months and 50,000 rows.

Who
Resellers and Customers
Roles
Owner, Admin, Staff
  • from and to are dates (YYYY-MM-DD). Without them: this month to date (daily) or the last 12 months (monthly).

Query parameters

  • granularityenumRequired

    Period length

    One ofdailymonthly

  • scope_typeenumRequired

    Rows per

    One ofdevicecustomerresellerplatform

  • scope_iduuid

    One device or organization (default: all in scope)

  • reseller_iduuid

    Only rows of this reseller (its customers, devices)

  • customer_iduuid

    Only rows of this customer (its devices)

  • fromdate

    First day (default: first of this month; monthly: 11 months before)

  • todate

    Last day (default: today)

  • basisenum

    Source of the figures (default api)

    One ofapicdr

Request
curl https://api.houndsat.com/api/exports/usage.csv?granularity=monthly&scope_type=customer \
  -H "Authorization: Bearer $HOUNDSAT_TOKEN"
Response200 OK
period_start,customer_id,customer_name,basis,uplink_bytes,downlink_bytes,total_bytes,total,active_device_count,retail_cost_cents
2026-09-01,c41e9a03-6b2f-4d8e-a571-0f3b9c2d7e14,Northwind Freight,cdr,412880,96120,509000,509 KB,3,4500