openapi: 3.0.0
info:
contact:
email: engineering@denim.com
name: Denim Engineering Team
url: https://www.denim.com
description: The Denim Public API can be used by 3rd parties to sync companies, debtor relationships, payee relationships, and create invoices within Denim's payment platform. This enables streamlined operations and job invoice data between transportation management systems and Denim.
title: Denim Public API Reference Documentation Companies API
version: 1.0.0
x-logo:
altText: Denim
backgroundColor: '#f5f5f5'
url: https://app.denim.com/images/branding/denim-logo-color.png
servers:
- description: Staging Environment
url: https://staging.denim.com
variables: {}
security:
- api_key: []
tags:
- description: A company in our system includes Payees, Debtors, and Factoring companies. Companies records are available globally in our ecosystem and shared by other clients.
externalDocs:
description: 'Guides: Companies'
url: https://help.denim.com/hc/en-us/articles/9403899854107-4-Mapping-and-Syncing-Companies
name: Companies
paths:
/api/v1/companies:
get:
callbacks: {}
description: "Returns a paginated list of company search results.\n\n### What you can search by\nThe `query` parameter is matched against:\n- `company_name` (token-based, normalized — see the `query` parameter for details)\n- `mc_number` (exact equality)\n- `dot_number` (exact equality)\n\nWhen `query` is omitted or empty, the endpoint returns all eligible companies ordered by\n`sort` (defaults to `company_name`). Inactive and duplicate companies are always\nexcluded; when `company_type=debtor`, companies that are payee-only (not also a debtor or client) are excluded.\n\n### Pagination\nResults are paginated. Defaults are `page=1` and `per_page=25`. The response always\nincludes `page`, `per_page`, `total_pages`, and `total_results` fields alongside `data`.\n\n### Multi-strategy text search\nFor non-numeric (or numeric-but-not-`exact_numeric_mode`) queries, the search tries:\n1. **Token ILIKE** against the normalized `company_name` (primary path).\n2. **Trigram similarity** (`similarity > 0.3`) fallback when ILIKE returns nothing.\n3. **Prefix full-text search** (`to_tsquery` with `:*` per token) as a final fallback.\n\nThis makes the search resilient to typos and partial-word queries.\n\n### How matches are ranked\nPass `sort=best_match` to rank results by relevance to `query`. For\n`company_type=debtor`, ranking factors in priority order are:\n\n1. Exact normalized name match.\n2. Number of query tokens found in `company_name`.\n3. Number of adjacent query-token pairs found in `company_name`.\n4. Active status (only applied to exact-name matches).\n5. Existence of a Client-Debtor Relationship between the requesting client and the company.\n6. CDR popularity (distinct clients with a non-deleted CDR for the company).\n7. Credit amount — `max(debtor.credit_limit, debtor.shared_credit_limit)`. When the\n company has multiple CDRs, the row with the highest credit wins.\n8. Trigram similarity (fuzzy fallback).\n9. Company `id` ascending (stable tiebreaker).\n\nSee the `sort` parameter for the non-debtor ranking chain.\n\n### MC / DOT exact lookup\nWhen `company_type=debtor` AND `sort=best_match` AND `query` is purely numeric, the\nsearch short-circuits to an exact `mc_number` / `dot_number` match and returns at most\none row in `data`. `total_results` still reflects the true number of matches so callers\ncan detect MC/DOT collisions.\n\n### Outputs\nEach result entry includes:\n- `company` — identity, address, status, `is_debtor` / `is_payee` / `is_factor` flags,\n and `last_payment_applied_at` (timestamp of the most recent payment received from this\n company across the platform — the customer's \"last paid date\").\n- `debtor` (only when `company.is_debtor=true`) — shared credit limit (`credit_limit`)\n and net terms (`net_terms`). Open-credit (`credit_limit - credit_used`) is not\n computed here; fetch it via the Client-Debtor Relationships endpoint when needed.\n- `client_debtor_relationship` (only when a non-deleted CDR exists for the requesting\n client) — relationship `id`, `status`, `noa_status`, `default_job_is_factored`, and\n `net_terms`. The `id` can be used as `client_debtor_relationship_id` in other API\n requests.\n- `payee` (only when `company.is_payee=true`) — factor company name.\n- `client_payee_relationship` (only when a non-deleted CPR exists) — relationship `id`,\n `contact_email`, and `days_to_pay_offset`. The `id` can be used as\n `client_payee_relationship_id` in other API requests.\n"
externalDocs:
description: 'API Integration Guides: Mapping and Syncing Companies'
url: https://help.denim.com/hc/en-us/articles/9403899854107-4-Mapping-and-Syncing-Companies
operationId: AxlePayWeb.Api.V1.CompanyController.index (2)
parameters:
- description: 'Search term matched against the company''s `company_name`, `mc_number`, and `dot_number`.
If omitted or empty, the endpoint returns all eligible companies (companies with
`status` of `duplicate` or `inactive` are always excluded), ordered by `sort`.
**Normalization applied to both the search term and `company_name` before matching:**
- Lowercased
- Punctuation replaced with spaces
- Consecutive whitespace collapsed to a single space
- Leading/trailing whitespace trimmed
**Name matching:** The normalized term is split into tokens. All tokens (other than
trailing business-suffix tokens) must appear in the normalized `company_name` for the
row to match. Trailing business suffixes — `inc`, `llc`, `corp`, `co`, `ltd`, `ltda`,
`gmbh`, `plc`, `sa`, `lp`, `llp`, `limited`, `corporation`, `incorporated`, `company` —
are treated as optional, so `"Acme Corp"` will still match a company named `"Acme Inc"`.
Single-character tokens (e.g. `"S.A.A."`) are matched as a single phrase.
**MC / DOT matching:** `mc_number` and `dot_number` are matched against the raw search
term using exact equality (in addition to the name match above), so `"12345678"` will
match a company whose `mc_number` is exactly `12345678`.
**Multi-strategy fallback:** If the token-based ILIKE search returns no rows, the
endpoint falls back to a PostgreSQL trigram-similarity search (`similarity > 0.3`),
and then to a prefix-aware full-text search on `company_name`. This makes the search
resilient to typos and partial-word queries.
**Exact numeric mode (debtor add-customer flow):** When `company_type=debtor` AND
`sort=best_match`, a purely numeric search term (whitespace stripped, leading zeros
ignored) bypasses name search entirely and matches only on exact `mc_number` or
`dot_number`. At most one row is returned in `data`; `total_results` still reflects
the true number of matches so the caller can detect MC/DOT collisions.
'
example: ABC Company Inc
in: query
name: query
required: false
schema:
type: string
- description: 'Type of company to sort by. Companies of the matching type are listed first (this is a
sort, not a filter). When `company_type=debtor`, results are additionally filtered to
exclude companies flagged as payees (`is_payee=true`), and the numeric-exact MC/DOT
match described under `query` is enabled when `sort=best_match`.
'
example: debtor
in: query
name: company_type
required: false
schema:
description: Searchable company types
enum:
- debtor
- payee
- factor
type: string
- description: When `true`, only companies with `status=active` or with an existing (non-deleted) Client-Debtor Relationship for the requesting client are returned. When `false` or omitted, the additional filter is not applied (companies with status `duplicate` and `inactive` are still always excluded).
example: true
in: query
name: active
required: false
schema:
type: boolean
- description: 'Sort order for results. Defaults to `company_name` when omitted or empty. See the
`sort` enum for the full list and ranking semantics. The `best_match` option applies a
multi-key ranking; see the operation description for details.
For `last_payment_applied_at` and `company_name` sorts, ordering composes as:
(1) matches of `company_type` first (e.g. with `company_type=debtor`, debtor rows
sort above non-debtor rows), then (2) rows whose `company_name` starts with the
trimmed, case-insensitive search term, then (3) the chosen sort field. The
`best_match` sort uses its own dedicated ranking chain and does not use the prefix
promotion above.
'
example: best_match
in: query
name: sort
required: false
schema:
description: "Valid sort parameters for company results.\n\n- `last_payment_applied_at` — sort by most-recent payment received (NULLs last).\n- `company_name` — alphabetical, case-insensitive, ascending.\n- `best_match` — relevance ranking against `query`. When `company_type=debtor` the\n ORDER BY chain is, in priority order:\n 1. Exact normalized name match.\n 2. Token match count (how many search tokens appear in `company_name`).\n 3. Consecutive token score (how many adjacent token pairs appear together —\n e.g. `\"American Logistics\"` outranks `\"American Eagle Logistics\"` for the\n query `\"American Logistics\"`).\n 4. Active status — only applied among exact-name matches; an active company\n outranks a non-active one with the same normalized name.\n 5. Has any existing (non-deleted) Client-Debtor Relationship for the client.\n 6. CDR popularity — number of distinct clients with a non-deleted CDR for the company.\n 7. Credit limit — `max(debtor.credit_limit, debtor.shared_credit_limit)`. When\n multiple Client-Debtor Relationships exist, the highest credit amount wins.\n 8. Trigram similarity against `company_name` (fuzzy fallback).\n 9. Company `id` ascending (stable tiebreaker).\n\n For non-debtor `company_type` (or when `company_type` is omitted) the chain is\n token count → consecutive score → trigram similarity → `id` ascending.\n"
enum:
- last_payment_applied_at
- company_name
- best_match
type: string
- description: The page of results to query.
example: 1
in: query
name: page
required: false
schema:
type: integer
- description: The number of entities per page of results.
example: 10
in: query
name: per_page
required: false
schema:
type: integer
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Company Index Response'
description: Company response
security:
- api_key: []
summary: Search for Companies
tags:
- Companies
/api/v1/companies/factors:
get:
callbacks: {}
description: Returns a list of all Factoring companies established in Denim's database. Return structure is similar to paginated results, however this will always return all factoring companies in 1 page.
externalDocs:
description: 'API Integration Guides: Mapping and Syncing Companies'
url: https://help.denim.com/hc/en-us/articles/9403899854107-4-Mapping-and-Syncing-Companies
operationId: AxlePayWeb.Api.V1.FactoringCompanyController.index
parameters: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/Factoring Company Index Response'
description: Factoring company response
security:
- api_key: []
summary: List Factoring Companies
tags:
- Companies
components:
schemas:
Debtor:
description: Debtor attributes shared across all clients (as opposed to per-relationship attributes, which live on `client_debtor_relationship`).
properties:
credit_limit:
description: Shared credit limit for this debtor (in cents). In the company search response this is the debtor's `shared_credit_limit`. When a per-relationship limit is required, use `client_debtor_relationship.credit_limit`.
nullable: true
type: integer
credit_used:
description: Shared credit used by this debtor (in cents). Not populated by the company search endpoint; use `client_debtor_relationship.credit_used` for the per-relationship amount.
nullable: true
type: integer
net_terms:
description: Default net terms (payment days) for the debtor. The per-relationship value on `client_debtor_relationship.net_terms` takes precedence when set.
nullable: true
type: integer
title: Debtor
type: object
Client-Payee Relationship:
description: Included only if there is an existing non-deleted Client-Payee Relationship for the requesting client.
properties:
contact_email:
description: Contact email at the payee company.
type: string
days_to_pay_offset:
description: Per-relationship offset (in days) added to the payee's standard pay terms.
nullable: true
type: integer
id:
description: usable as `client_payee_relationship_id`
type: integer
title: Client-Payee Relationship
type: object
Payee:
description: Payee Company Information
properties:
factor_company_name:
description: Name of the payee's factoring company, if they have one
type: string
id:
description: Payee ID
type: integer
title: Payee
type: object
Generic Company:
description: A generic company
properties:
city:
description: City
type: string
company_name:
description: Company name
type: string
dot_number:
description: DOT Number (Department of Transportation Number)
nullable: true
type: string
ein:
description: Federal EIN / Tax ID (9 digits)
nullable: true
type: string
id:
description: Company ID
type: integer
is_debtor:
description: Whether this company is a debtor type
nullable: true
type: boolean
is_factor:
description: Whether this company is a factor type
nullable: true
type: boolean
is_payee:
description: Whether this company is a payee type
nullable: true
type: boolean
last_payment_applied_at:
description: Timestamp of the most recent payment received from this company. For customer (debtor) search, this is the company's 'last paid date'. `null` if the company has never paid.
example: '2024-03-20T10:00:00Z'
format: datetime
nullable: true
type: string
mc_number:
description: FMCSA Motor Carrier Number (6-8 digits)
nullable: true
type: string
progress:
description: Company setup progress
enum:
- initial
- setup_started
- onboarding_started
- done
type: string
state:
description: State (2 Character Abbreviation)
type: string
status:
description: Company status. The search endpoint always excludes companies with status `duplicate` or `inactive`, so only the values listed below appear in search results.
enum:
- pending
- under_review
- active
- declined
type: string
title: Generic Company
type: object
Company Index Response:
description: Response schema for fetching companies
example:
data:
- client_debtor_relationship:
default_job_is_factored: true
id: 684
net_terms: 30
noa_status: pending_delivery
status: approved
company:
city: New York
company_name: Example Company with Exisiting Client-Debtor Relationship and Credit Limit
dot_number: null
ein: '123456789'
id: 1328
is_debtor: true
is_factor: null
is_payee: null
last_payment_applied_at: '2024-03-15T14:30:00Z'
mc_number: null
progress: initial
state: NY
status: active
debtor:
credit_limit: 5000000
net_terms: 30
- client_payee_relationship:
contact_email: tom@tomslogistics.com
days_to_pay_offset: 0
id: 606
company:
city: New York
company_name: Example Company with Exisiting Client-Payee Relationship and Factor
dot_number: '9876543'
ein: '123456789'
id: 1331
is_debtor: null
is_factor: null
is_payee: true
last_payment_applied_at: null
mc_number: '12345678'
progress: done
state: NY
status: active
payee:
factor_company_name: Lindsey Becker LLC
- company:
city: Omaha
company_name: Flowers and Valentine LLC
dot_number: '1122334'
ein: '123456789'
id: 20
is_debtor: null
is_factor: null
is_payee: null
last_payment_applied_at: null
mc_number: '12345678'
progress: done
state: NE
status: active
page: 1
per_page: 10
total_pages: 1
total_results: 3
properties:
data:
items:
properties:
client_debtor_relationship:
$ref: '#/components/schemas/Client-Debtor Relationship'
client_payee_relationship:
$ref: '#/components/schemas/Client-Payee Relationship'
company:
$ref: '#/components/schemas/Generic Company'
debtor:
$ref: '#/components/schemas/Debtor'
payee:
$ref: '#/components/schemas/Payee'
type: object
type: array
page:
description: Current page of results
type: integer
per_page:
description: Entities per page
type: integer
total_pages:
description: Total number of pages
type: integer
total_results:
description: Total number of results
type: integer
title: Company Index Response
type: object
Client-Debtor Relationship:
description: Included only when a non-deleted Client-Debtor Relationship exists between the requesting client and the company. The `id` is usable as `client_debtor_relationship_id` in other API requests.
properties:
average_dbt_past_60_days:
description: Average Days Beyond Terms
nullable: true
type: number
average_dso_past_60_days:
description: Average Days Sales Outstanding (DSO) in the past 60 days
nullable: true
type: number
default_job_is_factored:
description: Whether new jobs for this debtor default to factored funding.
nullable: true
type: boolean
id:
description: usable as `client_debtor_relationship_id`
type: integer
net_terms:
description: Net terms (payment days) for this relationship. Overrides `debtor.net_terms` when set.
nullable: true
type: integer
noa_status:
description: Notice-of-Assignment status for the relationship.
enum:
- pending_delivery
- delivered
- viewed
- confirmed
type: string
status:
description: Per-client approval status for this debtor relationship. `approved` relationships are ready for use. The system enforces at most one `approved` relationship per (client, debtor) — any prior duplicates are marked `rejected`. When the `best_match` sort returns multiple results for the same company, the highest-credit-amount row wins (see operation description).
enum:
- pending
- approved
- rejected
type: string
title: Client-Debtor Relationship
type: object
Factoring Company:
description: A factoring company
properties:
city:
description: City
type: string
company_name:
description: Company name
type: string
ein:
description: Federal EIN / Tax ID (9 digits)
nullable: true
type: string
id:
description: Company ID
type: integer
state:
description: State (2 Character Abbreviation)
type: string
title: Factoring Company
type: object
Factoring Company Index Response:
description: Response schema for fetching factoring companies
example:
data:
- company:
city: Atlanta
company_name: Best Trucking Company
ein: '123456789'
id: 35
state: GA
- company:
city: Chicago
company_name: Boyds Logistics
ein: '123456789'
id: 36
state: IL
- company:
city: Louisville
company_name: TLD Logistics Inc
ein: '123456789'
id: 37
state: KY
page: 1
per_page: 3
total_pages: 1
total_results: 3
properties:
data:
items:
properties:
company:
$ref: '#/components/schemas/Factoring Company'
type: object
type: array
page:
description: Current page of results
type: integer
per_page:
description: Entities per page
type: integer
total_pages:
description: Total number of pages
type: integer
total_results:
description: Total number of results
type: integer
title: Factoring Company Index Response
type: object
securitySchemes:
api_key:
in: header
name: x-api-key
type: apiKey
externalDocs:
description: API Integration Guides
url: https://help.denim.com/hc/en-us/sections/9403805442843-API-Integration-Guides