Manage suborganizations
Create, list, inspect, and update suborganizations under your parent organization.
Creating a suborganization
curl "$OPUSDNS_API_BASE/v1/organizations" \
--request POST \
--header "X-Api-Key: $OPUSDNS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"name": "Customer A",
"country_code": "DE",
"city": "Berlin",
"address_1": "Friedrichstraße 123",
"postal_code": "10117",
"currency": "EUR",
"default_locale": "de"
}'
Organization fields
| Field | Required | Description |
|---|---|---|
name |
Yes | Display name for the organization. |
billing_mode |
No | consolidated (default) or independent — see Billing modes. Cannot be changed after creation. |
country_code |
No | ISO 3166-1 alpha-2 country code. |
city |
No | City. |
address_1 |
No | First line of the street address. |
address_2 |
No | Second line of the street address. |
postal_code |
No | Postal or ZIP code. |
state |
No | State or province. |
currency |
No | Default currency for billing. |
default_locale |
No | Preferred locale for the organization. |
business_number |
No | Business registration number. |
tax_id |
No | Tax identification number (e.g., VAT ID). |
tax_id_type |
No | Type of tax ID. |
tax_rate |
No | Tax rate applied to transactions. |
attributes |
No | Custom key-value attributes (see Attributes). |
users |
No | Users to create in the new organization. |
Provisioning users at creation
You can create the suborganization and its initial users in a single request. Each user is scoped to the new organization — they have no visibility into the parent or other suborganizations:
curl "$OPUSDNS_API_BASE/v1/organizations" \
--request POST \
--header "X-Api-Key: $OPUSDNS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"name": "Customer A",
"country_code": "DE",
"city": "Berlin",
"address_1": "Friedrichstraße 123",
"postal_code": "10117",
"currency": "EUR",
"users": [
{
"username": "customer-a-admin",
"email": "admin@customer-a.com",
"first_name": "Alice",
"last_name": "Admin",
"locale": "de_DE"
},
{
"username": "customer-a-tech",
"email": "tech@customer-a.com",
"first_name": "Bob",
"last_name": "Tech",
"locale": "de_DE"
}
]
}'
Each user requires username, email, first_name, last_name, and
locale (underscore form, e.g. en_US). The first user in the list becomes
the organization's owner; subsequent users are created as admins.
You can add more users later with the User management API.
Billing modes
Every suborganization is created in one of two billing modes, set with the
billing_mode field on the create request:
consolidated (default) |
independent |
|
|---|---|---|
| Charges & invoices | Roll up to your (parent) account | The suborganization's own account |
| Wallet & payment methods | Yours | Its own wallet, balance, and payment methods |
| Extra required fields | None | currency, country_code |
billing_mode is permanent. It cannot be changed after creation — an
update request that includes billing_mode is rejected. Choose deliberately;
converting an organization between modes means deleting and recreating it.
Creating an independent suborganization
curl "$OPUSDNS_API_BASE/v1/organizations" \
--request POST \
--header "X-Api-Key: $OPUSDNS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"name": "Customer B (self-billed)",
"billing_mode": "independent",
"currency": "EUR",
"country_code": "DE",
"address_1": "Friedrichstraße 123",
"city": "Berlin",
"postal_code": "10117",
"tax_id": "DE123456789",
"users": [
{
"username": "customer-b-owner",
"email": "billing@customer-b.example",
"first_name": "Carol",
"last_name": "Owner",
"locale": "de_DE"
}
]
}'
Requirements and behavior:
-
currencyis required and must beEURorUSD. It becomes the organization's billing currency permanently. country_codeis required.-
A billing contact is needed: the first user in
users[]is used if present, otherwise your parent organization's owner. Include a full street address at creation — it is required later for checkout and balance top-ups. - Provisioning is synchronous and all-or-nothing: a successful response means the organization's billing account, wallet, and payment setup all exist. If anything fails, nothing is created.
- New independent suborganizations start on prepaid terms. Contact support to arrange different payment terms.
Errors
| HTTP | Error code | Meaning |
|---|---|---|
| 422 | ERROR_INDEPENDENT_BILLING_NOT_ALLOWED |
Independent billing is only available for suborganizations created directly under your top-level (billing) organization. |
| 422 | ERROR_INDEPENDENT_BILLING_ATTRIBUTES_INVALID |
currency or country_code missing or invalid — the response lists every problem in invalid_fields. |
| 422 | ERROR_INDEPENDENT_BILLING_CONTACT_NOT_FOUND |
No billing contact could be resolved — include a user in users[]. |
Viewing an independent suborganization's billing
An independent suborganization sees its own invoices, transactions, and
billing data through the normal billing endpoints. As the parent, you can view
a suborganization's billing by sending its ID in the X-Organization-Context
header on those same endpoints:
curl "$OPUSDNS_API_BASE/v1/organizations/organization_01h45.../transactions" \
--header "X-Api-Key: $OPUSDNS_API_KEY" \
--header "X-Organization-Context: organization_01h46..."
For a consolidated view of spend across your whole organization tree — including independent suborganizations — a monthly suborganization billing transactions report is available via the Reports API: each row is one transaction, with columns for the organization that incurred it and the organization that was billed for it.
Listing suborganizations
List all suborganizations under your current organization:
curl "$OPUSDNS_API_BASE/v1/organizations?page=1&page_size=25" \
--header "X-Api-Key: $OPUSDNS_API_KEY"
Searching and filtering
curl --get "$OPUSDNS_API_BASE/v1/organizations" \
--header "X-Api-Key: $OPUSDNS_API_KEY" \
--data-urlencode "search=Customer" \
--data-urlencode "country_code=DE" \
--data-urlencode "sort_by=name" \
--data-urlencode "sort_order=asc"
| Parameter | Description |
|---|---|
search |
Search by organization name. |
country_code |
Filter by country code. |
sort_by |
Sort by created_on, name, or country_code. |
sort_order |
asc or desc. |
page |
Page number (default: 1). |
page_size |
Results per page (default: 10, max: 1000). |
Getting organization details
Retrieve full details including billing data, active plan, and users:
curl "$OPUSDNS_API_BASE/v1/organizations/organization_01h45ytscbebyvny4gc8cr8ma2" \
--header "X-Api-Key: $OPUSDNS_API_KEY"
{
"organization_id": "organization_01h45ytscbebyvny4gc8cr8ma2",
"name": "Customer A",
"status": "active",
"country_code": "DE",
"parent_organization_id": "organization_01h35xrscbebyvny4gc8cr8ma2",
"account_balance": 150.00,
"active_plan": {
"plan_id": "plan_01h45ytscbebyvny4gc8cr8ma2",
"name": "Professional",
"plan_level": 2,
"amount": 29.99,
"currency": "EUR"
},
"billing_metadata": {
"billing_model": "prepaid",
"credit_limit": 500.00,
"customer_number": "CUST-00123"
},
"users": [
{
"user_id": "user_01h45ytscbebyvny4gc8cr8ma2",
"username": "customer-a-admin",
"email": "admin@customer-a.com",
"status": "active"
}
],
"created_on": "2026-01-15T10:00:00Z"
}
Response fields
| Field | Description |
|---|---|
organization_id |
Unique identifier. |
name |
Display name. |
status |
active or inactive. |
parent_organization_id |
The parent organization (your reseller account). |
account_balance |
Current account balance. |
active_plan |
The billing plan — includes plan ID, name, level, amount, and currency. |
billing_metadata |
Billing configuration — model (prepaid/postpaid), credit limit, customer number. |
users |
Users that belong to this organization. |
created_on |
When the organization was created. |
Updating an organization
Update any field with a PATCH request. Only include the fields you want to change:
curl "$OPUSDNS_API_BASE/v1/organizations/organization_01h45ytscbebyvny4gc8cr8ma2" \
--request PATCH \
--header "X-Api-Key: $OPUSDNS_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"name": "Customer A - Rebranded",
"city": "Munich",
"default_locale": "en"
}'

