/admin/domains
Path: /admin/domains
Namespace: admin
Resource: domains
Overview
The Domain resource represents tenants in the multi-tenant system. Each domain provides data isolation and can have its own configuration, users, invoices, items, and other resources.
Relationships
Model Associations
Domain connects to the following resources:
Address
- Type:
has_oneviaaddress_id - Field:
address_id - Description: Domain's business address (used as default seller). Each domain can have one default business address.
- Reverse: Address belongs to Domain (
address.domain) - API Access:
- Direct: Included in domain response as
address_idandaddressobject - Filter:
GET /admin/domains.json?q[address_id_eq]=123 - Via Address:
GET /admin/addresses/:address_id.json(domain's business address)
- Direct: Included in domain response as
- Key Pattern:
domain.addressis automatically used as default seller when creating invoices ifseller_idis omitted. - Related Documentation: Addresses
- Example: Get domain's business address (included in domain response):javascript
const domain = await fetch('/admin/domains/1.json', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json()); const address = domain.domain.address; // Address is included in domain response
Domain (Self-Referential - Hierarchical)
- Type:
belongs_to/has_manyviahost_id - Field:
host_id - Description: Parent domain for hierarchical multi-tenancy. Domains can have parent/child relationships for organizational structures.
- Reverse: Domain has many sub-domains (
domain.domainsordomain.children) - API Access:
- Direct: Included in domain response as
host_id(parent domain ID) - Filter:
GET /admin/domains.json?q[host_id_eq]=1 - Nested:
GET /admin/domains/:id/domains.json(sub-domains for a specific domain)
- Direct: Included in domain response as
- Example: Get all sub-domains:javascript
const subDomains = await fetch('/admin/domains/1/domains.json', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Domain[] (Multi-Domain Item Visibility)
- Type:
has_and_belongs_to_manyviadomains_itemsjoin table - Description: Items accessible to this domain. Items can be visible to multiple domains (multi-domain visibility).
- Reverse: Item has many domains via
domains_itemsjoin table - API Access:
- Direct: Included in domain response as
itemsarray (if present) - Filter:
GET /admin/items.json?q[domains_id_eq]=1(items visible to domain)
- Direct: Included in domain response as
- Related Documentation: Items
- Example: Get all items accessible to a domain:javascript
const items = await fetch('/admin/items.json?q[domains_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Reverse Associations
The following resources connect to Domain (all scoped by host_id):
User[]
- Type:
has_manyon User viahost_id - Description: All users for this domain. Users belong to domains and can only access their domain's data.
- API Access:
- Filter:
GET /admin/users.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Users
- Example: Get all users for a domain:javascript
const users = await fetch('/admin/users.json?q[host_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Invoice[]
- Type:
has_manyon Invoice viahost_id - Description: All invoices for this domain. Invoices are scoped to domains for multi-tenant isolation.
- API Access:
- Filter:
GET /admin/invoices.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Invoices
- Example: Get all invoices for a domain:javascript
const invoices = await fetch('/admin/invoices.json?q[host_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Address[]
- Type:
has_manyon Address viahost_id - Description: All addresses for this domain. Addresses are scoped to domains for multi-tenant isolation.
- API Access:
- Filter:
GET /admin/addresses.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Addresses
- Example: Get all addresses for a domain:javascript
const addresses = await fetch('/admin/addresses.json?q[host_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Payment[]
- Type:
has_manyon Payment viahost_id - Description: All payments for this domain. Payments are scoped to domains.
- API Access:
- Filter:
GET /admin/payments.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Payments
Item[]
- Type:
has_manyon Item viahost_id(plushas_and_belongs_to_manyviadomains_items) - Description: Items owned by this domain and items visible to this domain (via multi-domain visibility).
- API Access:
- Filter:
GET /admin/items.json?q[host_id_eq]=1(items owned by domain) - Filter:
GET /admin/items.json?q[domains_id_eq]=1(items visible to domain)
- Filter:
- Related Documentation: Items
AccountingAccount[]
- Type:
has_manyon AccountingAccount viahost_id - Description: Accounting accounts for this domain. Chart of accounts is scoped to domains.
- API Access:
- Filter:
GET /admin/accounting_accounts.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Accounting
AccountingEquation[]
- Type:
has_manyon AccountingEquation viahost_id - Description: Accounting transactions for this domain. Accounting equations are scoped to domains.
- API Access:
- Filter:
GET /admin/accounting_equations.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Accounting
SalesAgreement[]
- Type:
has_manyon SalesAgreement viahost_id - Description: Sales agreements for this domain. Sales agreements are scoped to domains.
- API Access:
- Filter:
GET /admin/sales_agreements.json?q[host_id_eq]=1
- Filter:
- Related Documentation: Sales Agreements
Relationship Patterns
Domain Address as Default Seller
- Use Case: Use domain's business address as default seller when creating invoices
- Example: When
seller_idis omitted,domain.addressis automatically used:javascriptconst invoice = await fetch('/admin/invoices.json', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: JSON.stringify({ invoice: { invoice_type: 'invoice', buyer_id: 2, // seller_id omitted - domain.address used automatically date: '2024-01-15' } }) }).then(r => r.json());
Hierarchical Domain Structure
- Use Case: Navigate parent-child relationships for organizational domain structures
- Example: Get all sub-domains:javascript
const subDomains = await fetch('/admin/domains.json?q[host_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Multi-Domain Item Visibility
- Use Case: Make items visible to multiple domains
- Example: Filter items visible to a specific domain:javascript
const visibleItems = await fetch('/admin/items.json?q[domains_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Domain Resource Filtering
- Use Case: Get all resources for a specific domain
- Example: Get all invoices for a domain:javascript
const domainInvoices = await fetch('/admin/invoices.json?q[host_id_eq]=1', { credentials: 'include', headers: { 'Accept': 'application/json' } }).then(r => r.json());
Key Features
- Multi-Tenancy: Each domain is isolated from others
- Host Association: Domains belong to a host
- Status Management: active, inactive status
- SSL Configuration: SSL certificate management (enable_ssl, disable_ssl)
- Domain Hierarchy: Domains can have parent/child relationships
- Data Isolation: All resources are scoped to domains
Multi-Tenant Architecture
- Host-Based Isolation: Data is scoped to domains via host associations
- Resource Scoping: All resources (invoices, addresses, items, etc.) are scoped to domains
- User Access: Users belong to domains and can only access their domain's data
- Domain Configuration: Each domain can have its own locale, timezone, and metadata
Available Operations
List Domains (GET)
Endpoint: GET /admin/domains.json
Query Parameters:
q[field_predicate]=value- Ransack query filters for advanced filteringscope=name- Apply named scope (e.g.,active,inactive)page=N- Page number for paginationper_page=N- Items per page (default: 25)
Request Examples:
curl -X GET "https://your-company.erpax.com/admin/domains.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"curl -X GET "https://your-company.erpax.com/admin/domains.json?q[name_cont]=Company" \
-H "Accept: application/json"curl -X GET "https://your-company.erpax.com/admin/domains.json?scope=active" \
-H "Accept: application/json"JavaScript Example:
const response = await fetch('/admin/domains.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const data = await response.json();Response (200 OK):
{
"domains": [
{
"id": 1,
"name": "company.erpax.com",
"host_id": null,
"status": "active",
"ssl_enabled": true,
"address_id": 1,
"created_at": "2024-01-10T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total_pages": 1,
"total_count": 5
}
}Show Domain (GET /:id)
Endpoint: GET /admin/domains/:id.json
Request Example:
curl -X GET "https://your-company.erpax.com/admin/domains/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"JavaScript Example:
const response = await fetch('/admin/domains/1.json', {
credentials: 'include',
headers: { 'Accept': 'application/json' }
});
const domain = await response.json();Response (200 OK):
{
"domain": {
"id": 1,
"name": "company.erpax.com",
"host_id": null,
"status": "active",
"ssl_enabled": true,
"address_id": 1,
"locale": "en",
"timezone": "UTC",
"created_at": "2024-01-10T10:00:00Z",
"updated_at": "2024-01-15T12:00:00Z"
}
}Create Domain (POST)
Endpoint: POST /admin/domains.json
Request Example:
curl -X POST "https://your-company.erpax.com/admin/domains.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"domain": {
"name": "newcompany.erpax.com",
"status": "active",
"address_id": 2,
"locale": "en",
"timezone": "America/New_York"
}
}'JavaScript Example:
const response = await fetch('/admin/domains.json', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
domain: {
name: 'newcompany.erpax.com',
status: 'active',
address_id: 2,
locale: 'en',
timezone: 'America/New_York'
}
})
});
const domain = await response.json();Response (201 Created):
{
"domain": {
"id": 2,
"name": "newcompany.erpax.com",
"status": "active",
"created_at": "2024-01-15T14:30:00Z"
}
}Update Domain (PATCH /:id)
Endpoint: PATCH /admin/domains/:id.json
Request Example:
curl -X PATCH "https://your-company.erpax.com/admin/domains/1.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"domain": {
"status": "inactive"
}
}'Response (200 OK):
{
"domain": {
"id": 1,
"status": "inactive",
"updated_at": "2024-01-15T15:00:00Z"
}
}Delete Domain (DELETE /:id)
Endpoint: DELETE /admin/domains/:id.json
Request Example:
curl -X DELETE "https://your-company.erpax.com/admin/domains/1.json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Response (204 No Content):
(empty response)Batch Actions
Endpoint: POST /admin/domains/batch_action.json
Available batch actions:
- activate - Activate selected domains
- suspend - Suspend selected domains
- enable_ssl - Enable SSL for selected domains
- disable_ssl - Disable SSL for selected domains
- create_archive - Create archive for selected domains
Request Example:
curl -X POST "https://your-company.erpax.com/admin/domains/batch_action.json" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Cookie: session_cookie" \
-d '{
"batch_action": "activate",
"collection_selection": [1, 2, 3]
}'Member Actions
Custom actions available on individual domains via API:
Activate Domain
Endpoint: POST /admin/domains/:id/activate
Description: Activate the domain.
Request Example:
curl -X POST "https://your-company.erpax.com/admin/domains/1/activate" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Response (200 OK):
{
"domain": {
"id": 1,
"status": "active",
"updated_at": "2024-01-15T15:00:00Z"
}
}Suspend Domain
Endpoint: POST /admin/domains/:id/suspend
Description: Suspend the domain.
Request Example:
curl -X POST "https://your-company.erpax.com/admin/domains/1/suspend" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Response (200 OK):
{
"domain": {
"id": 1,
"status": "inactive",
"updated_at": "2024-01-15T15:00:00Z"
}
}Enable SSL
Endpoint: POST /admin/domains/:id/enable_ssl
Description: Enable SSL/TLS for the domain.
Request Example:
curl -X POST "https://your-company.erpax.com/admin/domains/1/enable_ssl" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Response (200 OK):
{
"domain": {
"id": 1,
"ssl_enabled": true,
"updated_at": "2024-01-15T15:00:00Z"
}
}Disable SSL
Endpoint: POST /admin/domains/:id/disable_ssl
Description: Disable SSL/TLS for the domain.
Request Example:
curl -X POST "https://your-company.erpax.com/admin/domains/1/disable_ssl" \
-H "Accept: application/json" \
-H "Cookie: session_cookie"Response (200 OK):
{
"domain": {
"id": 1,
"ssl_enabled": false,
"updated_at": "2024-01-15T15:00:00Z"
}
}Scopes
- all (default) - All domains
- active - Active domains
- inactive - Inactive domains
Usage Example:
GET /admin/domains.json?scope=active
GET /admin/domains.json?scope=inactiveFilters
Available filters for searching and filtering domains:
- name_cont - Text filter - Search by domain name (contains)
- host - Select filter - Filter by host domain
- status - Select filter - Filter by status (active, inactive)
- ssl_enabled - Boolean filter - Filter by SSL enabled status
- created_at - Date filter - Filter by creation date
- updated_at - Date filter - Filter by update date
Filtering Examples:
# Search by name
GET /admin/domains.json?q[name_cont]=company
# Filter by status
GET /admin/domains.json?q[status_eq]=active
# Filter by SSL
GET /admin/domains.json?q[ssl_enabled_eq]=trueBusiness Rules
- Name Uniqueness: Domain names must be unique
- Host Association: Domains must belong to a host (or be root domains)
- Data Isolation: All resources are automatically scoped to domains
- Address Association: Domains can have an associated address used as default seller
- Status Management: Only active domains can be accessed by users