Skip to navigation

Account Structure

Understanding how Ottimate organizes accounts, companies, locations, and groups

Overview

Ottimate uses a tiered organizational hierarchy to manage accounts payable operations. Understanding this structure is essential for integration because every API request must be properly scoped to the correct company and location.

The hierarchy consists of:

  1. Account - The top-level organization (an Ottimate client)
  2. Company - A distinct accounting entity with its own chart of accounts and vendors
  3. Location - A subdivision within a company for invoice processing and approvals

Additionally, locations can be organized into Groups - optional labels that can span multiple companies in multi-company accounts.

Single-Company Account:

Structural Hierarchy:
Ottimate Account (racc_xxx)
│
└── Company 1 (id: 123)
├── Chart of Accounts (Dimensions)
├── Vendor List
└── Locations
├── Location A (id: 456)
├── Location B (id: 457)
├── Location C (id: 458)
└── Location D (id: 459)
Optional Groups (labels only):
├── North Region → Locations A, B
└── South Region → Locations C, D

Multi-Company Account:

Structural Hierarchy:
Ottimate Account (racc_xxx)
│
├── Company 1 (id: 123)
│ ├── Chart of Accounts (Dimensions)
│ ├── Vendor List
│ └── Locations
│ ├── Location A (id: 456)
│ └── Location B (id: 457)
│
└── Company 2 (id: 789)
├── Chart of Accounts (Dimensions)
├── Vendor List
└── Locations
├── Location D (id: 460)
└── Location E (id: 461)
Groups (can span across companies):
├── West Region → Location A (Company 1), Location D (Company 2)
└── East Region → Location B (Company 1), Location E (Company 2)

Key Principle: Data does not cross company boundaries. Each company has completely separate dimensions, vendors, and invoice workflows.

Identifier naming across endpoints

The Accounts API returns companies and locations with a plain id. That same value is what you pass on the other endpoints, where it is named for the entity it points at:

ValueReturned asSent as
Account IDid on GET /v1/accounts (a racc_-prefixed string){account_id} in the Accounts API paths
Company IDid on GET /v1/accounts/{account_id}/companiesottimate_company_id on vendors, invoices, dimensions, and catalog; company_id on payments
Location IDid on GET /v1/accounts/{account_id}/locationsottimate_location_id on invoices, purchase orders, and receipts; location_id on payments

There is no ottimate_company_id or ottimate_location_id field in an Accounts API response — those names only ever appear in requests to other APIs.


Hierarchy Components

Client Accounts (racc_)

A client account represents an organization using Ottimate to automate accounts payable processes. This is the top-level entity that Ottimate provisions during onboarding.

Key Characteristics:

  • Unique identifier format: racc_ prefix (e.g., racc_90832490382904802384)
  • Contains one or more companies
  • API credentials (Client ID, Client Secret) are scoped to an account
  • Billing and subscription are managed at the account level

For API Integrators

Accounts are provisioned by Ottimate during the Onboarding process before you begin integration development. By the time you receive your API credentials, your account structure (account, companies, and locations) is already configured.

Structure is read-only, with one exception. You cannot create, rename, or delete accounts, companies, locations, or groups through the API, and you cannot move a location between companies or groups. For any of those, contact your Ottimate Partner Manager.

The one setting you can change is a location’s Basic Approval flag, via PATCH /v1/accounts/{id}/locations/{location_id}. Everything else on the structure is GET-only.

Listing the accounts you can reach:

Your credentials may be scoped to more than one account. GET /v1/accounts returns every account your API user can access, which is where an integration usually starts.

TaskEndpoint
List all accounts you can accessGET /v1/accounts
Filter accounts by nameGET /v1/accounts?search={account_name}
{
"version": "1.0.0",
"count": 1,
"page": 1,
"limit": 50,
"results": [
{
"id": "racc_a1b2c3d4e5f6",
"name": "Acme Restaurant Group",
"created_date": "2024-01-15T10:30:00Z",
"created_date_utc": "2024-01-15T10:30:00.000000Z",
"company_count": 5,
"location_count": 23
}
]
}

Response Fields:

FieldTypeDescription
idstringThe account ID, racc_ prefixed. Use it as {account_id} in the paths below.
namestringAccount name
created_datestringAccount creation timestamp
created_date_utcstringUTC equivalent of created_date, ISO 8601 with a Z suffix
company_countintegerNumber of companies in this account. Companies have no active flag, so this counts all of them.
location_countintegerNumber of active locations across all companies in this account

Companies

A company is a distinct accounting entity within a client account. Each company maintains its own:

  • Chart of accounts - Separate set of dimensions (GL accounts, departments, etc.)
  • Vendor list - Vendors are company-specific
  • Accounting rules - Separate coding and approval policies
  • ERP connection - Each company connects to one ERP instance

When to Use Multiple Companies

Use separate companies when:

  • Different ERP systems - Subsidiary A uses NetSuite, Subsidiary B uses QuickBooks
  • Separate legal entities - Each entity files taxes separately and maintains separate books
  • Distinct chart of accounts - Each entity has a completely different GL structure
  • Separate vendor relationships - Vendors are managed independently between entities

Use a single company with multiple locations when:

  • Same ERP system - All locations use the same accounting software
  • Shared chart of accounts - Same GL structure across all locations
  • Shared vendor list - Vendors serve multiple locations
  • Centralized accounting - Single accounting team manages all locations

Examples

Multi-Company Scenario:

Restaurant Group (Account)
├── Brand A LLC (Company 1) - Uses NetSuite
│ └── 50 Brand A locations
└── Brand B Corp (Company 2) - Uses QuickBooks
└── 30 Brand B locations

Single-Company Scenario:

Regional Restaurant Chain (Account)
└── ABC Restaurants Inc (Company 1) - Uses NetSuite
├── Boston Location
├── New York Location
└── Philadelphia Location

Accessing Company Information

Companies are pre-configured during account onboarding. Use the companies endpoint to retrieve company IDs for your API calls:

TaskEndpoint
List all companies for an accountGET /v1/accounts/{account_id}/companies
Filter companies by nameGET /v1/accounts/{account_id}/companies?search={company_name}
Get company detailsIncluded in the list response above

List Companies Example:

GET https://api.ottimate.com/v1/accounts/racc_90832490382904802384/companies

Response:

{
"version": "1.0.0",
"count": 2,
"page": 1,
"limit": 10,
"results": [
{
"id": 123,
"name": "Acme Inc.",
"location_count": 5,
"plan": null
},
{
"id": 124,
"name": "Acme Inc. - Downtown",
"location_count": 1,
"plan": null
}
]
}

Response Fields:

FieldTypeDescription
versionstringThe API version that rendered the response. See API versioning below.
countintegerTotal number of companies matching the request
pageintegerThe page returned
limitintegerPage size
idintegerThe Ottimate-assigned company ID (send it as ottimate_company_id in other API calls)
namestringCompany name
location_countintegerNumber of active locations in this company — the same active-only basis as GET /v1/accounts/{account_id}/locations
planstringReserved. Always null in the current release — subscription plan is held at the account level, not per company.

Pagination fields: List responses carry count, page, and limit only. There are no next or previous link fields — page through results by incrementing page until you have seen count records.


Locations

A location is a subdivision within a company used to organize invoice processing, permissions, and approval workflows. Locations share the same chart of accounts and vendor list as their parent company.

Key Characteristics:

  • Belongs to exactly one company
  • Shares the company’s dimensions and vendors
  • Can have location-specific approval policies
  • Can have location-specific user permissions
  • Can have location-specific email to receive invoices
  • Used to route invoices to appropriate approvers

Accessing Location Information

Locations are pre-configured during account onboarding. Use the locations endpoint to retrieve location IDs for invoice creation and filtering:

TaskEndpoint
List all locations for an accountGET /v1/accounts/{account_id}/locations
Filter locations by nameGET /v1/accounts/{account_id}/locations?search={location_name}
Toggle Basic Approval for a locationPATCH /v1/accounts/{account_id}/locations/{location_id}

List Locations Example:

GET https://api.ottimate.com/v1/accounts/racc_90832490382904802384/locations

Response:

{
"version": "1.0.0",
"count": 3,
"page": 1,
"limit": 10,
"results": [
{
"id": 456,
"name": "Main Kitchen",
"company": "Acme Inc.",
"company_id": 123,
"group": "West Region",
"uses_approval": true
},
{
"id": 457,
"name": "Downtown Branch",
"company": "Acme Inc.",
"company_id": 123,
"group": "West Region",
"uses_approval": false
},
{
"id": 458,
"name": "East Side Location",
"company": "Acme Inc.",
"company_id": 123,
"group": "East Region",
"uses_approval": false
}
]
}

Response Fields:

FieldTypeDescription
versionstringThe API version that rendered the response. See API versioning below.
idintegerThe Ottimate-assigned location ID (send it as ottimate_location_id in invoice creation)
namestringLocation name
companystringParent company name
company_idintegerParent company ID — the id from the companies list
location_groupstringThe group this location belongs to, or null. Returned when you send X-API-Version: 1.1.0.
groupstringDeprecated. The same value as location_group. Returned for X-API-Version: 1.0.0 and for requests that send no version header.
uses_approvalbooleanWhether Basic Approval is enabled for this location

Only active locations are returned. The active-only filter is applied server-side and cannot be turned off — there is no parameter for listing de-activated locations. If you cache this list (recommended, see Best Practices), treat a location that has disappeared from a later fetch as de-activated rather than deleted, and stop routing new invoices to it.

is_active for a single location is available on the response to PATCH /v1/accounts/{id}/locations/{location_id}.

Filtering by company: The locations endpoint returns all locations for an account across all companies, and has no server-side company filter. Use the company_id field in the response to select the locations for a specific company client-side. Prefer company_id over the company name for this — names are not guaranteed unique or stable.


API versioning

The Accounts API supports two versions, selected with the X-API-Version request header:

X-API-VersionBehavior
absentSame as 1.0.0
1.0.0Locations return the deprecated group field
1.1.0Locations return location_group instead of group

Every response echoes the version that rendered it in its top-level version field, so you can confirm which one you got.

An unrecognized version falls back to 1.0.0 silently — it is not an error. If you send X-API-Version: 2.0.0, you get the 1.0.0 response shape and "version": "1.0.0" in the body, with no warning. Check the version field rather than assuming your header was honored.

Migrating from group to location_group:

curl https://api.ottimate.com/v1/accounts/racc_90832490382904802384/locations \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "X-API-Version: 1.1.0"

The two fields carry the same value, so migration is a rename: send the 1.1.0 header and read location_group. group is still returned for 1.0.0 and unversioned requests.


Groups

A group is an optional label applied to a location, used for reporting, permissions, and workflow management within Ottimate. Groups are not a scoping tier for the API: no request is scoped to a group, and nothing is inherited through one.

Key Characteristics:

  • A group contains 1 or more locations
  • A location can only belong to 1 group (or none)
  • Groups are optional - locations can exist without being assigned to a group
  • Groups are configured through the Ottimate Onboarding Tool, not the API

There is no Groups API. Groups are surfaced only as a name on the Location object — location_group (or the deprecated group) on GET /v1/accounts/{id}/locations. There is no endpoint that lists groups, and no group parameter on any endpoint to filter or scope by.

To work with groups, read the locations list and group the results client-side by location_group. To scope requests to a set of locations, pass the individual location IDs.

The PATCH locations endpoint additionally returns group_id and group_name for the single location it responds with — this is the only place a group ID is exposed.

Groups in Single-Company Accounts:

In a single-company account, groups organize locations within the same company:

  • Regional organization - “North Region” and “South Region” groups organize stores by geography
  • Department-based grouping - “Corporate Offices” vs “Warehouse Locations”
  • Reporting - Track AP metrics by location grouping

Groups in Multi-Company Accounts (Cross-Company Groups):

In multi-company accounts, groups can span across companies, creating “cross-company groups”:

  • Regional organization - “West Coast” group contains locations from multiple subsidiary companies
  • Cross-company reporting - Track AP metrics across subsidiaries by region/division
  • Shared management - A regional manager oversees locations from multiple legal entities