StabisoDocs

API reference

Intercompany

Trade between two entities of one organization: the approved relationship (with its VAT group and transfer-pricing record), the draft bill an invoice creates in the counterpart and its acceptance, loans with their interest, group dividends, the settlements, and the reconciliation of the two sides.

Operation Summary Scope Idempotency-Key
GET /v1/ic/links List the intercompany links read
GET /v1/ic/links/{link_id} Get an intercompany link read
POST /v1/ic/links/{link_id}/reject Reject the mirror of an intercompany document post
POST /v1/ic/links/{link_id}/retry Make the counterpart of a link again post
GET /v1/ic/loans List the intercompany loans read
POST /v1/ic/loans Request an intercompany loan draft required
GET /v1/ic/loans/{loan_id} Get an intercompany loan read
POST /v1/ic/loans/{loan_id}/drawdowns Draw down an intercompany loan post required
POST /v1/ic/loans/{loan_id}/interest Accrue the interest of an intercompany loan post required
POST /v1/ic/loans/{loan_id}/repayments Repay an intercompany loan post required
GET /v1/ic/movements List the intercompany movements read
GET /v1/ic/movements/{movement_id} Get an intercompany movement read
GET /v1/ic/reconciliation Reconcile the intercompany balances read
GET /v1/ic/relationships List the intercompany relationships read
POST /v1/ic/relationships Request an intercompany relationship draft required
GET /v1/ic/relationships/{relationship_id} Get an intercompany relationship read
PATCH /v1/ic/relationships/{relationship_id} Change, suspend or resume an intercompany relationship draft
POST /v1/ic/settlements Settle intercompany interest or a group dividend post required

List the intercompany links

The evidence that a posted invoice or credit note of one entity has a counterpart in the other, newest first: both documents, the status, why a counterpart could not be made (error), who posted the origin (that person does not accept the mirror), who accepted or rejected the mirror and why. A drafted mirror is accepted like any bill: a person in the receiving entity recodes it if needed and submits it (POST /v1/documents/{id}/submit).

Required scope read (admin implies every scope)
Operation id list_links_v1_ic_links_get

Parameters

In Name Type Required Description
query relationship string (uuid) or null Only the links of this relationship (GET /v1/ic/relationships).
query status "accepted" | "drafted" | "mirror_rejected" | "pending" | "rejected" | "waiting" or null Only links in this state: drafted are the mirror documents waiting to be accepted, pending those whose counterpart could not be made.
query entity string or null Only links where this entity is either side.
query limit integer At most this many links, newest first. (min 1; max 500; default 100)

Example request

curl "$ERP_URL/v1/ic/links" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of LinkOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "counter": {
      "document_date": "2026-09-21",
      "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
      "entity": "DE01",
      "kind": "purchase_bill",
      "party_code": "IC-CH01",
      "status": "draft",
      "total": "10000.00"
    },
    "created_at": "2026-09-21T10:15:00Z",
    "currency": "CHF",
    "id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
    "kind": "invoice",
    "net_total": "10000.00",
    "origin": {
      "document_date": "2026-09-21",
      "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
      "entity": "CH01",
      "kind": "sales_invoice",
      "number": "INV-2026-000001",
      "party_code": "IC-DE01",
      "status": "posted",
      "total": "10000.00"
    },
    "origin_posted_by": {
      "id": "user:alice",
      "name": "Alice",
      "type": "human"
    },
    "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
    "status": "drafted"
  }
]

Get an intercompany link

One link with its origin and counterpart documents. 404 when it does not exist or belongs to another organization.

Required scope read (admin implies every scope)
Operation id get_link_v1_ic_links__link_id__get

Parameters

In Name Type Required Description
path link_id string (uuid) yes Id of the link (GET /v1/ic/links).

Example request

curl "$ERP_URL/v1/ic/links/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK LinkOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "counter": {
    "document_date": "2026-09-21",
    "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
    "entity": "DE01",
    "kind": "purchase_bill",
    "party_code": "IC-CH01",
    "status": "draft",
    "total": "10000.00"
  },
  "created_at": "2026-09-21T10:15:00Z",
  "currency": "CHF",
  "id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
  "kind": "invoice",
  "net_total": "10000.00",
  "origin": {
    "document_date": "2026-09-21",
    "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
    "entity": "CH01",
    "kind": "sales_invoice",
    "number": "INV-2026-000001",
    "party_code": "IC-DE01",
    "status": "posted",
    "total": "10000.00"
  },
  "origin_posted_by": {
    "id": "user:alice",
    "name": "Alice",
    "type": "human"
  },
  "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
  "status": "drafted"
}

POST /v1/ic/links/{link_id}/reject

Reject the mirror of an intercompany document

The receiving entity refuses the draft: it is voided and the link becomes rejected with the reason, which the sender sees; the sender corrects with a credit note. A difference between the two sides that a rejected mirror leaves is unexplained in the reconciliation until then. Humans only, and not the person who posted the origin (accept_own_ic_document). 409 for a link whose mirror is not a draft any more.

Required scope post (admin implies every scope)
Idempotency-Key not used
Operation id reject_link_v1_ic_links__link_id__reject_post

Parameters

In Name Type Required Description
path link_id string (uuid) yes Id of the link (GET /v1/ic/links).

Request body

application/json (required): RejectInput

Field Type Required Description
reason string yes Why the receiving entity refuses the document; the sender sees it. (min length 3; max length 1000)

Example request

curl -X POST "$ERP_URL/v1/ic/links/3fa85f64-5717-4562-b3fc-2c963f66afa6/reject" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "The fee was agreed at 8,000, not 10,000"
}'

Responses

Status Meaning Body
200 OK LinkOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "counter": {
    "document_date": "2026-09-21",
    "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
    "entity": "DE01",
    "kind": "purchase_bill",
    "party_code": "IC-CH01",
    "status": "draft",
    "total": "10000.00"
  },
  "created_at": "2026-09-21T10:15:00Z",
  "currency": "CHF",
  "id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
  "kind": "invoice",
  "net_total": "10000.00",
  "origin": {
    "document_date": "2026-09-21",
    "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
    "entity": "CH01",
    "kind": "sales_invoice",
    "number": "INV-2026-000001",
    "party_code": "IC-DE01",
    "status": "posted",
    "total": "10000.00"
  },
  "origin_posted_by": {
    "id": "user:alice",
    "name": "Alice",
    "type": "human"
  },
  "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
  "status": "drafted"
}

POST /v1/ic/links/{link_id}/retry

Make the counterpart of a link again

Repeat the construction of the counterpart for a link that is pending (its error says why: no VAT number, a vendor number already used in the receiving entity, a missing account) or waiting (a credit note whose invoice's mirror has been posted since). The origin stays posted whatever happens here; the answer shows the new state. 409 for a link that is not pending or waiting.

Required scope post (admin implies every scope)
Idempotency-Key not used
Operation id retry_link_v1_ic_links__link_id__retry_post

Parameters

In Name Type Required Description
path link_id string (uuid) yes Id of the link (GET /v1/ic/links).

Example request

curl -X POST "$ERP_URL/v1/ic/links/3fa85f64-5717-4562-b3fc-2c963f66afa6/retry" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK LinkOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "counter": {
    "document_date": "2026-09-21",
    "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
    "entity": "DE01",
    "kind": "purchase_bill",
    "party_code": "IC-CH01",
    "status": "draft",
    "total": "10000.00"
  },
  "created_at": "2026-09-21T10:15:00Z",
  "currency": "CHF",
  "id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
  "kind": "invoice",
  "net_total": "10000.00",
  "origin": {
    "document_date": "2026-09-21",
    "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
    "entity": "CH01",
    "kind": "sales_invoice",
    "number": "INV-2026-000001",
    "party_code": "IC-DE01",
    "status": "posted",
    "total": "10000.00"
  },
  "origin_posted_by": {
    "id": "user:alice",
    "name": "Alice",
    "type": "human"
  },
  "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
  "status": "drafted"
}

GET /v1/ic/loans

List the intercompany loans

The loans of the organization, oldest first, each with its terms, who requested and approved it, the approval that waits, and what it stands at from its movements: the principal outstanding, the day interest is accrued_through and the interest_open (accrued and not settled). 404 for an entity that does not exist.

Required scope read (admin implies every scope)
Operation id list_loans_v1_ic_loans_get

Parameters

In Name Type Required Description
query entity string or null Only the loans this entity lends or borrows.
query status "active" | "closed" | "draft" or null Only loans in this state.
query limit integer At most this many loans, oldest first. (min 1; max 500; default 200)

Example request

curl "$ERP_URL/v1/ic/loans" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of LoanOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "reference": "string",
    "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "lender": "string",
    "borrower": "string",
    "currency": "string",
    "facility_amount": "string",
    "interest_rate_percent": "string",
    "interest_basis": "string",
    "day_count": "30/360",
    "start_date": "2026-09-21",
    "maturity_date": "2026-09-21",
    "lender_bank_account": "string",
    "lender_bank_balance": "string",
    "lender_bank_currency": "",
    "borrower_bank_account": "string",
    "net_investment": true,
    "status": "active",
    "principal": "string",
    "accrued_through": "2026-09-21",
    "interest_open": "string",
    "requested_by": {},
    "approved_by": {},
    "approved_at": "2026-09-21T09:30:00Z",
    "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "closed_at": "2026-09-21T09:30:00Z",
    "created_at": "2026-09-21T09:30:00Z"
  }
]

POST /v1/ic/loans

Request an intercompany loan

Ask for a loan between the two entities of an active relationship. It is written draft and a second person approves its terms (POST /v1/approvals/{approval_id}/approve; the policy action approve_ic_agreement, human only): the amount, the currency, the fixed rate with its arm's-length interest_basis in words (recorded, never judged), the day count, the dates, the two bank accounts and whether the loan is part of the net investment (IAS 21.15). The approval is bound to the terms by a digest and they never change afterwards. 409 role_missing names an account the lender (ic_loan_receivable, ic_other_receivable, ic_interest_income) or the borrower (ic_loan_payable, ic_other_payable, ic_interest_expense) lacks, 409 without an active relationship or for a reference in use, 422 for a bank account that is not an active asset account. Humans only. Needs an Idempotency-Key.

Required scope draft (admin implies every scope)
Idempotency-Key required
Operation id create_loan_v1_ic_loans_post

Request body

application/json (required): LoanInput

Field Type Required Description
reference string yes The loan's reference, unique in the organization. (min length 1; max length 40)
lender string yes Code (or id) of the entity that lends.
borrower string yes Code (or id) of the entity that borrows.
currency string or null ISO 4217 currency of the loan. Omitted: the lender's functional currency. (min length 3; max length 3)
facility_amount decimal string yes The agreed amount: what may be drawn at most (a decimal string). (greater than 0)
interest_rate_percent decimal string yes Fixed annual rate in percent, e.g. 3.0000. (min 0; max 100)
interest_basis string yes The arm's-length basis the approvers accepted, in words (the benchmark, its source and date). Recorded, never judged. (min length 3; max length 2000)
day_count "30/360" | "act/360" | "act/365" yes act/360, act/365 (fixed) or 30/360 (European, 30E/360).
start_date string (date) yes First day a drawdown may be dated.
maturity_date string (date) yes The day the loan falls due; after the start.
lender_bank_account string yes Code of the lender's bank account in its chart (an asset account): where drawdowns are paid from and repayments come in.
borrower_bank_account string yes Code of the borrower's bank account in its chart (an asset account).
net_investment boolean IAS 21.15: settlement is neither planned nor likely, so the loan is part of the net investment in a foreign operation and the consolidation takes its exchange differences to the translation reserve (IAS 21.32). (default false)

Example request

curl -X POST "$ERP_URL/v1/ic/loans" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "borrower": "DE01",
  "borrower_bank_account": "1010",
  "currency": "EUR",
  "day_count": "act/360",
  "facility_amount": "500000.00",
  "interest_basis": "3-month EURIBOR of 30 September 2026 plus 0.50 %, the benchmark the tax adviser documented on 25 September 2026",
  "interest_rate_percent": "3.0000",
  "lender": "CH01",
  "lender_bank_account": "1020",
  "maturity_date": "2029-09-30",
  "reference": "L-2026-01",
  "start_date": "2026-10-01"
}'

Responses

Status Meaning Body
201 Created LoanOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "reference": "string",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lender": "string",
  "borrower": "string",
  "currency": "string",
  "facility_amount": "string",
  "interest_rate_percent": "string",
  "interest_basis": "string",
  "day_count": "30/360",
  "start_date": "2026-09-21",
  "maturity_date": "2026-09-21",
  "lender_bank_account": "string",
  "lender_bank_balance": "string",
  "lender_bank_currency": "",
  "borrower_bank_account": "string",
  "net_investment": true,
  "status": "active",
  "principal": "string",
  "accrued_through": "2026-09-21",
  "interest_open": "string",
  "requested_by": {},
  "approved_by": {},
  "approved_at": "2026-09-21T09:30:00Z",
  "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "closed_at": "2026-09-21T09:30:00Z",
  "created_at": "2026-09-21T09:30:00Z"
}

GET /v1/ic/loans/{loan_id}

Get an intercompany loan

One loan with its terms and what it stands at. 404 when it does not exist or belongs to another organization.

Required scope read (admin implies every scope)
Operation id get_loan_v1_ic_loans__loan_id__get

Parameters

In Name Type Required Description
path loan_id string (uuid) yes Id of the loan (GET /v1/ic/loans).

Example request

curl "$ERP_URL/v1/ic/loans/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK LoanOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "reference": "string",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "lender": "string",
  "borrower": "string",
  "currency": "string",
  "facility_amount": "string",
  "interest_rate_percent": "string",
  "interest_basis": "string",
  "day_count": "30/360",
  "start_date": "2026-09-21",
  "maturity_date": "2026-09-21",
  "lender_bank_account": "string",
  "lender_bank_balance": "string",
  "lender_bank_currency": "",
  "borrower_bank_account": "string",
  "net_investment": true,
  "status": "active",
  "principal": "string",
  "accrued_through": "2026-09-21",
  "interest_open": "string",
  "requested_by": {},
  "approved_by": {},
  "approved_at": "2026-09-21T09:30:00Z",
  "approval_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "closed_at": "2026-09-21T09:30:00Z",
  "created_at": "2026-09-21T09:30:00Z"
}

POST /v1/ic/loans/{loan_id}/drawdowns

Draw down an intercompany loan

The lender pays out: Dr ic_loan_receivable / Cr bank in the lender, Dr bank / Cr ic_loan_payable in the borrower, in the loan's currency at the ECB rate of the value date. 409 for a loan that is not active, a value date outside the start and the maturity, or an amount beyond what is left of the facility; 409 when the date is on or before the day interest is accrued through (accrue first, the day count would be wrong). Both entities' entries are made in one transaction and each goes through its entity's posting policy (an entry that needs approval waits, and the reconciliation lists it as loan_movement_missing until it posts). A payout that takes the lender's bank account below zero in the books on the value date is made, with a warnings line saying so and its warning_reasons by code (the money may be there and not booked yet). Needs an Idempotency-Key.

Required scope post (admin implies every scope)
Idempotency-Key required
Operation id drawdown_v1_ic_loans__loan_id__drawdowns_post

Parameters

In Name Type Required Description
path loan_id string (uuid) yes Id of the loan (GET /v1/ic/loans).

Request body

application/json (required): MovementInput

Field Type Required Description
value_date string (date) yes The day the money moves; both entries are dated it.
amount decimal string yes In the loan's currency (a decimal string). (greater than 0)
reference string or null Your reference, e.g. the bank's; optional. (max length 200)

Example request

curl -X POST "$ERP_URL/v1/ic/loans/3fa85f64-5717-4562-b3fc-2c963f66afa6/drawdowns" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": "500000.00",
  "value_date": "2026-10-01"
}'

Responses

Status Meaning Body
201 Created MovementOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "dividend_declared",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_reference": "string",
  "value_date": "2026-09-21",
  "amount": "string",
  "currency": "string",
  "reference": "string",
  "creditor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "debtor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "settles_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "detail": {},
  "created_by": {},
  "created_at": "2026-09-21T09:30:00Z",
  "warnings": [
    "string"
  ],
  "warning_reasons": [
    {
      "words": "string",
      "code": "string",
      "details": {},
      "text": "string"
    }
  ]
}

POST /v1/ic/loans/{loan_id}/interest

Accrue the interest of an intercompany loan

Accrue the interest from the day after the last accrual (or from the start) through through, over the principal outstanding each day, by the loan's day count, rounded half to even once: the lender Dr ic_other_receivable / Cr ic_interest_income, the borrower Dr ic_interest_expense / Cr ic_other_payable. detail.segments shows each stretch of days with its principal. 409 for a day on or before the last accrual, for a day in a period that has not started yet (period_not_started), or when the interest is zero (no principal in the period). The close check ic_interest warns while a loan with principal outstanding is not accrued through the period's end. Both entities' entries are made in one transaction and each goes through its entity's posting policy. Needs an Idempotency-Key.

Required scope post (admin implies every scope)
Idempotency-Key required
Operation id accrue_v1_ic_loans__loan_id__interest_post

Parameters

In Name Type Required Description
path loan_id string (uuid) yes Id of the loan (GET /v1/ic/loans).

Request body

application/json (required): InterestInput

Field Type Required Description
through string (date) yes Accrue the interest up to and including this day, from the day after the last accrual (or from the first drawdown).

Example request

curl -X POST "$ERP_URL/v1/ic/loans/3fa85f64-5717-4562-b3fc-2c963f66afa6/interest" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "through": "2026-10-31"
}'

Responses

Status Meaning Body
201 Created MovementOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "dividend_declared",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_reference": "string",
  "value_date": "2026-09-21",
  "amount": "string",
  "currency": "string",
  "reference": "string",
  "creditor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "debtor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "settles_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "detail": {},
  "created_by": {},
  "created_at": "2026-09-21T09:30:00Z",
  "warnings": [
    "string"
  ],
  "warning_reasons": [
    {
      "words": "string",
      "code": "string",
      "details": {},
      "text": "string"
    }
  ]
}

POST /v1/ic/loans/{loan_id}/repayments

Repay an intercompany loan

The borrower pays back principal: each side's loan balance is relieved at its carrying amount and the bank at the ECB rate of the day; the difference is the realised exchange result (detail.realised). The loan is closed when its principal and its open interest are both zero. 409 for more than the principal outstanding or a date on or before the last accrual. Both entities' entries are made in one transaction and each goes through its entity's posting policy. One that takes the borrower's bank account below zero in the books is made, with a warnings line. Needs an Idempotency-Key.

Required scope post (admin implies every scope)
Idempotency-Key required
Operation id repayment_v1_ic_loans__loan_id__repayments_post

Parameters

In Name Type Required Description
path loan_id string (uuid) yes Id of the loan (GET /v1/ic/loans).

Request body

application/json (required): MovementInput

Field Type Required Description
value_date string (date) yes The day the money moves; both entries are dated it.
amount decimal string yes In the loan's currency (a decimal string). (greater than 0)
reference string or null Your reference, e.g. the bank's; optional. (max length 200)

Example request

curl -X POST "$ERP_URL/v1/ic/loans/3fa85f64-5717-4562-b3fc-2c963f66afa6/repayments" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": "500000.00",
  "value_date": "2026-10-01"
}'

Responses

Status Meaning Body
201 Created MovementOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "dividend_declared",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_reference": "string",
  "value_date": "2026-09-21",
  "amount": "string",
  "currency": "string",
  "reference": "string",
  "creditor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "debtor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "settles_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "detail": {},
  "created_by": {},
  "created_at": "2026-09-21T09:30:00Z",
  "warnings": [
    "string"
  ],
  "warning_reasons": [
    {
      "words": "string",
      "code": "string",
      "details": {},
      "text": "string"
    }
  ]
}

GET /v1/ic/movements

List the intercompany movements

The drawdowns, repayments, interest accruals, settlements and declared group dividends, by value date, each with both entities' entries and their state (a dividend's shareholder entry stays draft until a person of the shareholder accepts it). Append-only: a movement is never changed or deleted.

Required scope read (admin implies every scope)
Operation id list_movements_v1_ic_movements_get

Parameters

In Name Type Required Description
query loan string (uuid) or null Only the movements of this loan.
query entity string or null Only movements where this entity is either side.
query kind "dividend_declared" | "interest_accrual" | "loan_drawdown" | "loan_repayment" | "settlement" or null Only movements of this kind.
query start string (date) or null Value date on or after this day.
query end string (date) or null Value date on or before this day.
query limit integer At most this many, by value date. (min 1; max 500; default 200)

Example request

curl "$ERP_URL/v1/ic/movements" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of MovementOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "kind": "dividend_declared",
    "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "loan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "loan_reference": "string",
    "value_date": "2026-09-21",
    "amount": "string",
    "currency": "string",
    "reference": "string",
    "creditor": {
      "entity": "string",
      "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "number": "string",
      "status": "string"
    },
    "debtor": {
      "entity": "string",
      "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
      "number": "string",
      "status": "string"
    },
    "settles_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "detail": {},
    "created_by": {},
    "created_at": "2026-09-21T09:30:00Z",
    "warnings": [
      "string"
    ],
    "warning_reasons": [
      {
        "words": "string",
        "code": "string",
        "details": null,
        "text": "string"
      }
    ]
  }
]

GET /v1/ic/movements/{movement_id}

Get an intercompany movement

One movement with both entries. 404 when it does not exist or belongs to another organization.

Required scope read (admin implies every scope)
Operation id get_movement_v1_ic_movements__movement_id__get

Parameters

In Name Type Required Description
path movement_id string (uuid) yes Id of the movement (GET /v1/ic/movements).

Example request

curl "$ERP_URL/v1/ic/movements/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK MovementOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "dividend_declared",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_reference": "string",
  "value_date": "2026-09-21",
  "amount": "string",
  "currency": "string",
  "reference": "string",
  "creditor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "debtor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "settles_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "detail": {},
  "created_by": {},
  "created_at": "2026-09-21T09:30:00Z",
  "warnings": [
    "string"
  ],
  "warning_reasons": [
    {
      "words": "string",
      "code": "string",
      "details": {},
      "text": "string"
    }
  ]
}

GET /v1/ic/reconciliation

Reconcile the intercompany balances

For each relationship and each currency of its open items, what the two entities hold towards each other in the document currency (so the FX revaluation cannot disturb it): a_receivable, a_payable, b_receivable, b_payable, the nets and difference = a_net + b_net, zero when both sides agree. The same figures per link and per group document nobody linked, each with a reason: timing reasons (mirror_missing, mirror_draft, mirror_pending_approval, payment_in_transit, cutoff) are explained and the counterpart's to resolve; mirror_rejected, unlinked_document and amount_differs are unexplained. The carrying amounts in each functional currency and the difference converted to the tolerance currency at the ECB rate of the day are for information; the tolerance applies to that figure. status is the result the close check ic_reconciled takes: pass, warn (timing items only) or fail (a part is unexplained). Open means what the books hold: the posted payments and credit notes up to the day.

Required scope read (admin implies every scope)
Operation id reconciliation_v1_ic_reconciliation_get

Parameters

In Name Type Required Description
query as_of string (date) yes The day the open items are read as of, ISO 8601.
query relationship string (uuid) or null Only this relationship; default: every relationship that is not pending.
query entity string or null Only the relationships of this entity.

Example request

curl "$ERP_URL/v1/ic/reconciliation?as_of=2026-09-30" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK Reconciliation
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "as_of": "2026-09-30",
  "relationships": [
    {
      "carrying": [
        {
          "balance": "10000.00",
          "entity": "CH01",
          "functional_currency": "CHF"
        },
        {
          "balance": "0.00",
          "entity": "DE01",
          "functional_currency": "EUR"
        }
      ],
      "currencies": [
        {
          "a_net": "10000.00",
          "a_payable": "0.00",
          "a_receivable": "10000.00",
          "b_net": "0.00",
          "b_payable": "0.00",
          "b_receivable": "0.00",
          "currency": "CHF",
          "difference": "10000.00"
        }
      ],
      "detail": "1 item differs, all timing: the counterpart books its part",
      "difference_in_tolerance_currency": "10000.00",
      "entity_a": "CH01",
      "entity_b": "DE01",
      "items": [
        {
          "counter": {
            "document_date": "2026-09-21",
            "document_id": "7c2d6a0e-2a64-4d36-b0a3-9e5a1d6f2c02",
            "entity": "DE01",
            "kind": "purchase_bill",
            "party_code": "IC-CH01",
            "status": "draft",
            "total": "10000.00"
          },
          "counter_open": "0.00",
          "currency": "CHF",
          "difference": "10000.00",
          "explained": true,
          "link_id": "e3a1f0b2-6d7c-4b8a-9c0d-1e2f3a4b5c03",
          "origin": {
            "document_date": "2026-09-21",
            "document_id": "0b9b8a53-1c4e-4f3a-8f55-3f2c3b8a6d01",
            "entity": "CH01",
            "kind": "sales_invoice",
            "number": "INV-2026-000001",
            "party_code": "IC-DE01",
            "status": "posted",
            "total": "10000.00"
          },
          "origin_open": "10000.00",
          "reason": "mirror_draft"
        }
      ],
      "relationship_id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
      "status": "warn",
      "tolerance_amount": "1.00",
      "tolerance_currency": "CHF",
      "unexplained_in_tolerance_currency": "0.00"
    }
  ]
}

GET /v1/ic/relationships

List the intercompany relationships

The relationships of the organization, oldest first, each with its terms, who requested and approved them, the approval that waits (approval_id), the four group parties, and the counts the Intercompany page shows: open_mirrors (drafts waiting to be accepted), not_made (counterparts that could not be made) and rejected_mirrors; each is the number of links GET /v1/ic/links lists for that status. 404 for an entity that does not exist.

Required scope read (admin implies every scope)
Operation id list_relationships_v1_ic_relationships_get

Parameters

In Name Type Required Description
query status "active" | "pending" | "suspended" or null Only relationships in this state.
query entity string or null Only the relationships of this entity (code or id), on either side.
query limit integer At most this many relationships, oldest first. (min 1; max 500; default 200)

Example request

curl "$ERP_URL/v1/ic/relationships" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK array of RelationshipOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

[
  {
    "approved_at": "2026-09-01T09:30:00Z",
    "approved_by": {
      "id": "user:bob",
      "name": "Bob",
      "type": "human"
    },
    "created_at": "2026-09-01T09:00:00Z",
    "entity_a": "CH01",
    "entity_a_name": "Demo AG",
    "entity_b": "DE01",
    "entity_b_name": "Demo GmbH",
    "id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
    "markup_percent": "5",
    "mirror_mode": "draft",
    "not_made": 0,
    "open_mirrors": 1,
    "parties": [
      {
        "code": "IC-DE01",
        "entity": "CH01",
        "kind": "customer",
        "party_id": "1a2b3c4d-0000-4000-8000-000000000001",
        "status": "active"
      },
      {
        "code": "IC-CH01",
        "entity": "DE01",
        "kind": "vendor",
        "party_id": "1a2b3c4d-0000-4000-8000-000000000002",
        "status": "active"
      }
    ],
    "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
    "pricing_documented_on": "2026-06-30",
    "pricing_method": "cost_plus",
    "rejected_mirrors": 0,
    "requested_by": {
      "id": "user:alice",
      "name": "Alice",
      "type": "human"
    },
    "status": "active",
    "terms_digest": "9d1f3c0b5e7a4c2f8b6d0a1e3c5f7b9d2a4c6e8f0b1d3f5a7c9e1b3d5f7a9c0e",
    "tolerance_amount": "1.00",
    "tolerance_currency": "CHF",
    "vat_group": "none"
  }
]

POST /v1/ic/relationships

Request an intercompany relationship

Ask for intercompany trade between two entities of the organization. The relationship is written pending and a second person approves its terms (POST /v1/approvals/{approval_id}/approve; the approver is never the requester): the mirror mode, the tolerance of the reconciliation, the VAT group and the transfer-pricing record (method, mark-up, the basis in words, the date of the documentation), which the approvers see before they decide; the ERP records it and never judges a price. The approval is bound to those terms by a digest: changing any of them later is a new request. On approval, in the same transaction, the relationship becomes active and each entity gets a customer and a vendor that is the other entity (code IC-<code>), active at once, with name, address, VAT number and bank accounts read from the other entity's record. Refused with 409 role_missing while an entity has no account with the role ic_ar_control or ic_ap_control (the answer names the entity, the role and the code its chart template suggests), 409 when the pair already has a relationship, and 422 for a VAT group across the border or without a start date and reference, a cost_plus without mark-up or an empty pricing basis. Humans only: the policy action approve_ic_relationship denies agents. Needs an Idempotency-Key.

Required scope draft (admin implies every scope)
Idempotency-Key required
Operation id create_relationship_v1_ic_relationships_post

Request body

application/json (required): RelationshipInput

Field Type Required Description
mirror_mode "draft" | "post" draft (default): the document made in the counterpart is a draft that a person there accepts. post: the system posts it at once under the system policy, a standing flow the approval authorises (a monthly management fee); never the default. (default "draft")
tolerance_amount decimal string The difference the reconciliation counts as agreed: rounding only, in tolerance_currency. Default 1.00. (min 0; default "1")
tolerance_currency string or null ISO 4217 currency of the tolerance. Default: the functional currency of entity_a as named in the request. (pattern ^[A-Z]{3}$)
vat_group "ch_vat_group" | "de_organschaft" | "none" none (default), ch_vat_group (a Swiss VAT group, Art. 13 MWSTG: two Swiss entities) or de_organschaft (a German tax group, § 2 para. 2 no. 2 UStG: two German entities). From vat_group_from the supplies between the two are outside the scope of VAT (vat_scope outside, reason vat_group or organschaft) and no VAT report or return has them. Never between a Swiss and a German entity. (default "none")
vat_group_from string (date) or null The date from which the VAT group applies (a Swiss group starts at the beginning of a tax period, Art. 13 para. 2 MWSTG); required with a VAT group, refused without one. Documents dated before it carry VAT as usual.
vat_group_reference string or null The registration or documentation of the group (a notice of the tax authority, the Organträger's confirmation); required with a VAT group. (max length 500)
pricing_method "cost_plus" | "cup" | "other" | "profit_split" | "resale_price" | "tnmm" yes The transfer-pricing method the approvers accepted: cup (comparable uncontrolled price), resale_price, cost_plus, tnmm (transactional net margin), profit_split or other. The system records it and never judges a price.
markup_percent decimal string or null The mark-up in percent where the method has one; required for cost_plus. (min 0; max 1000)
pricing_basis string yes The basis in words: the benchmark or study and its date. Mandatory: an approval without it is refused (§ 1 para. 1 AStG, OECD Model Convention Art. 9). (min length 3; max length 2000)
pricing_documented_on string (date) yes The date the documentation of the prices was made (§ 90 para. 3 AO).
entity_a string yes Code (or id) of one entity of the pair, e.g. CH01.
entity_b string yes Code (or id) of the other entity, e.g. DE01.

Example request

curl -X POST "$ERP_URL/v1/ic/relationships" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "entity_a": "CH01",
  "entity_b": "DE01",
  "markup_percent": "5",
  "mirror_mode": "draft",
  "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
  "pricing_documented_on": "2026-06-30",
  "pricing_method": "cost_plus",
  "tolerance_amount": "1.00",
  "tolerance_currency": "CHF",
  "vat_group": "none"
}'

Responses

Status Meaning Body
201 Created RelationshipOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "approved_at": "2026-09-01T09:30:00Z",
  "approved_by": {
    "id": "user:bob",
    "name": "Bob",
    "type": "human"
  },
  "created_at": "2026-09-01T09:00:00Z",
  "entity_a": "CH01",
  "entity_a_name": "Demo AG",
  "entity_b": "DE01",
  "entity_b_name": "Demo GmbH",
  "id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
  "markup_percent": "5",
  "mirror_mode": "draft",
  "not_made": 0,
  "open_mirrors": 1,
  "parties": [
    {
      "code": "IC-DE01",
      "entity": "CH01",
      "kind": "customer",
      "party_id": "1a2b3c4d-0000-4000-8000-000000000001",
      "status": "active"
    },
    {
      "code": "IC-CH01",
      "entity": "DE01",
      "kind": "vendor",
      "party_id": "1a2b3c4d-0000-4000-8000-000000000002",
      "status": "active"
    }
  ],
  "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
  "pricing_documented_on": "2026-06-30",
  "pricing_method": "cost_plus",
  "rejected_mirrors": 0,
  "requested_by": {
    "id": "user:alice",
    "name": "Alice",
    "type": "human"
  },
  "status": "active",
  "terms_digest": "9d1f3c0b5e7a4c2f8b6d0a1e3c5f7b9d2a4c6e8f0b1d3f5a7c9e1b3d5f7a9c0e",
  "tolerance_amount": "1.00",
  "tolerance_currency": "CHF",
  "vat_group": "none"
}

GET /v1/ic/relationships/{relationship_id}

Get an intercompany relationship

One relationship with its terms, the transfer-pricing record, the approval that waits and a change of terms that waits (pending_terms), and its group parties. 404 when it does not exist or belongs to another organization.

Required scope read (admin implies every scope)
Operation id get_relationship_v1_ic_relationships__relationship_id__get

Parameters

In Name Type Required Description
path relationship_id string (uuid) yes Id of the relationship (GET /v1/ic/relationships).

Example request

curl "$ERP_URL/v1/ic/relationships/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY"

Responses

Status Meaning Body
200 OK RelationshipOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "approved_at": "2026-09-01T09:30:00Z",
  "approved_by": {
    "id": "user:bob",
    "name": "Bob",
    "type": "human"
  },
  "created_at": "2026-09-01T09:00:00Z",
  "entity_a": "CH01",
  "entity_a_name": "Demo AG",
  "entity_b": "DE01",
  "entity_b_name": "Demo GmbH",
  "id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
  "markup_percent": "5",
  "mirror_mode": "draft",
  "not_made": 0,
  "open_mirrors": 1,
  "parties": [
    {
      "code": "IC-DE01",
      "entity": "CH01",
      "kind": "customer",
      "party_id": "1a2b3c4d-0000-4000-8000-000000000001",
      "status": "active"
    },
    {
      "code": "IC-CH01",
      "entity": "DE01",
      "kind": "vendor",
      "party_id": "1a2b3c4d-0000-4000-8000-000000000002",
      "status": "active"
    }
  ],
  "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
  "pricing_documented_on": "2026-06-30",
  "pricing_method": "cost_plus",
  "rejected_mirrors": 0,
  "requested_by": {
    "id": "user:alice",
    "name": "Alice",
    "type": "human"
  },
  "status": "active",
  "terms_digest": "9d1f3c0b5e7a4c2f8b6d0a1e3c5f7b9d2a4c6e8f0b1d3f5a7c9e1b3d5f7a9c0e",
  "tolerance_amount": "1.00",
  "tolerance_currency": "CHF",
  "vat_group": "none"
}

PATCH /v1/ic/relationships/{relationship_id}

Change, suspend or resume an intercompany relationship

Send one kind of change. status: suspended (with a reason) stops new intercompany postings at once, one person; the open items stay and settle normally. status: active on a suspended relationship, and new terms (mirror mode, tolerance, VAT group, pricing record), are approval requests: the terms in force stay until a second person approves, and the answer's approval_id names the request (the approver sees the pricing record again). A relationship that was never approved takes new terms at once and asks again; after a rejection any PATCH (even {}, the terms unchanged) asks again. refresh_parties alone reads the name, address, VAT number, country and bank accounts of the two entities again into their four group parties (which are not edited by hand: a payment to a group entity goes only to a bank account registered for it). 409 while a request about the relationship already waits, for a change that changes nothing and for a status the relationship cannot move to; 422 for terms that are not coherent. Humans only.

Required scope draft (admin implies every scope)
Idempotency-Key not used
Operation id update_relationship_v1_ic_relationships__relationship_id__patch

Parameters

In Name Type Required Description
path relationship_id string (uuid) yes Id of the relationship (GET /v1/ic/relationships).

Request body

application/json (required): RelationshipUpdate

Field Type Required Description
status "active" | "suspended" or null suspended stops new intercompany postings at once (one person, with a reason); open items stay and settle normally. active on a suspended relationship asks a second person to approve resuming.
mirror_mode "draft" | "post" or null New mirror mode.
tolerance_amount decimal string or null New tolerance. (min 0)
tolerance_currency string or null New tolerance currency. (pattern ^[A-Z]{3}$)
vat_group "ch_vat_group" | "de_organschaft" | "none" or null New VAT group.
vat_group_from string (date) or null New VAT group start date.
vat_group_reference string or null New VAT group reference. (max length 500)
pricing_method "cost_plus" | "cup" | "other" | "profit_split" | "resale_price" | "tnmm" or null New method.
markup_percent decimal string or null New mark-up. (min 0; max 1000)
pricing_basis string or null New pricing basis. (min length 3; max length 2000)
pricing_documented_on string (date) or null New date of the documentation.
refresh_parties boolean Read the name, address, VAT number, country and bank accounts of the two entities again into their four customer and vendor records, which are not edited by hand. Alone: it changes no terms. (default false)
reason string or null Why: required to suspend, kept with a change of terms in the audit trail. (min length 3; max length 1000)

Example request

curl -X PATCH "$ERP_URL/v1/ic/relationships/3fa85f64-5717-4562-b3fc-2c963f66afa6" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "reason": "Entity DE01 is being sold",
  "status": "suspended"
}'

Responses

Status Meaning Body
200 OK RelationshipOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
404 The resource does not exist, or belongs to another organization (not_found). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "approved_at": "2026-09-01T09:30:00Z",
  "approved_by": {
    "id": "user:bob",
    "name": "Bob",
    "type": "human"
  },
  "created_at": "2026-09-01T09:00:00Z",
  "entity_a": "CH01",
  "entity_a_name": "Demo AG",
  "entity_b": "DE01",
  "entity_b_name": "Demo GmbH",
  "id": "6f1c1c1e-5a53-4a4e-9b7f-0d2f6b2b9a10",
  "markup_percent": "5",
  "mirror_mode": "draft",
  "not_made": 0,
  "open_mirrors": 1,
  "parties": [
    {
      "code": "IC-DE01",
      "entity": "CH01",
      "kind": "customer",
      "party_id": "1a2b3c4d-0000-4000-8000-000000000001",
      "status": "active"
    },
    {
      "code": "IC-CH01",
      "entity": "DE01",
      "kind": "vendor",
      "party_id": "1a2b3c4d-0000-4000-8000-000000000002",
      "status": "active"
    }
  ],
  "pricing_basis": "Cost plus 5 % on the cost of the shared services, benchmark study of 2026-06-30 (median of 12 comparable service providers)",
  "pricing_documented_on": "2026-06-30",
  "pricing_method": "cost_plus",
  "rejected_mirrors": 0,
  "requested_by": {
    "id": "user:alice",
    "name": "Alice",
    "type": "human"
  },
  "status": "active",
  "terms_digest": "9d1f3c0b5e7a4c2f8b6d0a1e3c5f7b9d2a4c6e8f0b1d3f5a7c9e1b3d5f7a9c0e",
  "tolerance_amount": "1.00",
  "tolerance_currency": "CHF",
  "vat_group": "none"
}

POST /v1/ic/settlements

Settle intercompany interest or a group dividend

Pay accrued interest of a loan, or a declared group dividend (the id of its dividend_declared movement): the debtor Dr ic_other_payable / Cr bank, the creditor Dr bank / Cr ic_other_receivable, each balance relieved at its carrying amount and the bank at the ECB rate of the day. The bank accounts default to the loan's (for a dividend, the accounts with the role bank). 409 for more than is open, or a dividend whose shareholder has not accepted its entry yet. Both entities' entries are made in one transaction and each goes through its entity's posting policy. One that takes the debtor's bank account below zero in the books is made, with a warnings line. Needs an Idempotency-Key.

Required scope post (admin implies every scope)
Idempotency-Key required
Operation id settle_v1_ic_settlements_post

Request body

application/json (required): SettlementInput

Field Type Required Description
loan string (uuid) or null Settle the loan's accrued interest; or name a dividend.
dividend string (uuid) or null Settle a declared group dividend: the id of its dividend_declared movement.
value_date string (date) yes The day of the payment.
amount decimal string yes In the currency of what is settled; at most what is open. (greater than 0)
payer_bank_account string or null The paying entity's bank account code; default the loan's (for a dividend the account with the role bank).
payee_bank_account string or null The receiving entity's bank account code; default as above.
reference string or null Your reference. (max length 200)

Example request

curl -X POST "$ERP_URL/v1/ic/settlements" \
  -H "Authorization: Bearer $ERP_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "amount": "1250.00",
  "loan": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "value_date": "2026-11-05"
}'

Responses

Status Meaning Body
201 Created MovementOut
401 Missing or invalid API key (unauthorized). ErrorEnvelope
403 The caller lacks the required scope (missing_right, with scope), the key belongs to no person where a person is needed (forbidden), or the approval policy denies the action (policy_denied, with action and rule_id). ErrorEnvelope
409 The request conflicts with the data: an Idempotency-Key reused with a different request, a closed period, or an integrity rule of the database (conflict, integrity_violation). ErrorEnvelope
422 Validation failed: the error envelope (validation_failed). For a malformed body or parameter its message is in sentences ("Line 2: the quantity must be above zero") and fields lists each error with pydantic's loc, type and msg beside its sentence (message) and its parts, to word it in another language: items (name and number from 1: line 2), field (its name as sent) and the rule it breaks with its limit, count and choices (none for a validator's own sentence); FastAPI's own detail list stays beside the envelope. HTTPValidationError

Example response (shape)

{
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "kind": "dividend_declared",
  "relationship_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "loan_reference": "string",
  "value_date": "2026-09-21",
  "amount": "string",
  "currency": "string",
  "reference": "string",
  "creditor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "debtor": {
    "entity": "string",
    "entry_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
    "number": "string",
    "status": "string"
  },
  "settles_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "detail": {},
  "created_by": {},
  "created_at": "2026-09-21T09:30:00Z",
  "warnings": [
    "string"
  ],
  "warning_reasons": [
    {
      "words": "string",
      "code": "string",
      "details": {},
      "text": "string"
    }
  ]
}

Schemas

BalanceRow

A loan, its accrued interest or a declared group dividend, and what the two sides hold of it (ADR-0025, section 6).

Field Type Required Description
kind "dividend" | "interest" | "loan" yes loan (the principal), interest (accrued and not paid) or dividend (declared and not paid).
item_id string (uuid) yes The loan (GET /v1/ic/loans), or the dividend's dividend_declared movement.
reference string yes The loan's or the dividend's reference.
currency string yes Currency of the item.
a_balance string yes What entity_a holds of it: a receivable positive, a payable negative.
b_balance string yes What entity_b holds of it, signed the same way.
difference string yes a_balance + b_balance; zero when both agree.
reason "amount_differs" | "cutoff" | "loan_movement_missing" | "mirror_draft" | "mirror_missing" | "mirror_pending_approval" | "mirror_rejected" | "payment_in_transit" | "unlinked_document" or null yes loan_movement_missing (an entry of a movement is not posted yet on one side: explained) or amount_differs (unexplained); null when they agree.
explained boolean yes True when the difference is a timing item (or zero).

CarryingRow

Field Type Required Description
entity string yes Entity code.
functional_currency string yes The entity's functional currency.
balance string yes What the books of the entity hold towards the partner on the group accounts at the day, in its functional currency: receivables positive, payables negative. For information; the revaluation moves it, the reconciliation does not.

CurrencyRow

The open items of a pair in one document currency, in the document currency: neither functional currency, so a revaluation cannot disturb the comparison.

Field Type Required Description
currency string yes Document currency.
a_receivable string yes entity_a's receivable from entity_b: its open sales invoices to it, less its open credit notes.
a_payable string yes entity_a's payable to entity_b: its open bills.
b_receivable string yes entity_b's receivable from entity_a.
b_payable string yes entity_b's payable to entity_a.
a_net string yes a_receivable less a_payable.
b_net string yes b_receivable less b_payable.
difference string yes a_net plus b_net: zero when both sides agree exactly.

DocumentRef

Field Type Required Description
document_id string (uuid) yes Id of the document.
entity string yes Code of the entity whose books hold it.
number string or null yes Its number; null while it is a draft.
kind string yes sales_invoice, sales_credit_note, purchase_bill ...
status string yes draft, pending_approval, posted, rejected, void.
document_date string (date) yes Its date.
party_code string yes The customer or vendor, which is the other entity.
total string yes Gross total in the document currency.

EntryRef

Field Type Required Description
entity string yes Entity code.
entry_id string (uuid) yes The journal entry.
number string or null yes Its number once posted.
status string yes draft (a dividend the shareholder has not accepted yet), pending_approval, posted or rejected.

GroupPartyOut

Field Type Required Description
entity string yes Code of the entity whose books hold the party.
kind "customer" | "vendor" yes customer or vendor.
code string yes The party's code, e.g. IC-DE01.
party_id string (uuid) yes Id of the party.
status string yes active: the relationship's approval activated it.

InterestInput

Field Type Required Description
through string (date) yes Accrue the interest up to and including this day, from the day after the last accrual (or from the first drawdown).

ItemRow

One link, or one group document without a link, and what its two sides hold.

Field Type Required Description
link_id string (uuid) or null yes The link; null for a document without one.
origin DocumentRef yes The origin document, or the unlinked document.
counter DocumentRef or null yes The counterpart, when there is one.
currency string yes Document currency.
origin_open string yes Open amount of the origin as of the day (posted).
counter_open string yes Open amount of the counterpart; 0 until posted.
difference string yes origin_open less counter_open (for an unlinked bill the minus of its open amount); zero when both sides agree.
reason "amount_differs" | "cutoff" | "loan_movement_missing" | "mirror_draft" | "mirror_missing" | "mirror_pending_approval" | "mirror_rejected" | "payment_in_transit" | "unlinked_document" or null yes Why they differ: a timing reason (mirror_missing, mirror_draft, mirror_pending_approval, payment_in_transit, cutoff) is explained and the counterpart's to resolve; mirror_rejected, unlinked_document and amount_differs are unexplained. Null when difference is zero.
explained boolean yes True when the difference is wholly a timing reason (or zero).

LinkOut

Field Type Required Description
id string (uuid) yes Id of the link.
relationship_id string (uuid) yes The relationship it belongs to.
kind "credit_note" | "invoice" yes invoice (a sales invoice and its purchase bill) or credit_note.
status "accepted" | "drafted" | "mirror_rejected" | "pending" | "rejected" | "waiting" yes pending (the counterpart could not be made: error says why; POST /v1/ic/links/{id}/retry), waiting (a credit note whose invoice's mirror is not posted), drafted (the counterpart is a draft a person accepts), accepted (posted), rejected (the receiver refused it; the sender corrects with a credit note) or mirror_rejected (a credit note of an invoice whose mirror was rejected: nothing to credit).
currency string yes Document currency of both documents.
net_total string yes The origin's net total: the counterpart must equal it to be posted.
error string or null yes Why the counterpart could not be made, while pending.
origin DocumentRef yes The document that was posted.
counter DocumentRef or null yes The counterpart in the other entity; null while pending or waiting.
origin_posted_by object yes Who posted the origin: this person does not accept the mirror.
created_at string (date-time) yes When the origin was posted and linked (UTC).
accepted_by object or null yes Who accepted (posted) the mirror.
accepted_at string (date-time) or null yes When (UTC).
rejected_by object or null yes Who rejected the mirror.
rejected_at string (date-time) or null yes When (UTC).
reject_reason string or null yes Why it was rejected.

LoanInput

Field Type Required Description
reference string yes The loan's reference, unique in the organization. (min length 1; max length 40)
lender string yes Code (or id) of the entity that lends.
borrower string yes Code (or id) of the entity that borrows.
currency string or null ISO 4217 currency of the loan. Omitted: the lender's functional currency. (min length 3; max length 3)
facility_amount decimal string yes The agreed amount: what may be drawn at most (a decimal string). (greater than 0)
interest_rate_percent decimal string yes Fixed annual rate in percent, e.g. 3.0000. (min 0; max 100)
interest_basis string yes The arm's-length basis the approvers accepted, in words (the benchmark, its source and date). Recorded, never judged. (min length 3; max length 2000)
day_count "30/360" | "act/360" | "act/365" yes act/360, act/365 (fixed) or 30/360 (European, 30E/360).
start_date string (date) yes First day a drawdown may be dated.
maturity_date string (date) yes The day the loan falls due; after the start.
lender_bank_account string yes Code of the lender's bank account in its chart (an asset account): where drawdowns are paid from and repayments come in.
borrower_bank_account string yes Code of the borrower's bank account in its chart (an asset account).
net_investment boolean IAS 21.15: settlement is neither planned nor likely, so the loan is part of the net investment in a foreign operation and the consolidation takes its exchange differences to the translation reserve (IAS 21.32). (default false)

LoanOut

Field Type Required Description
id string (uuid) yes Id of the loan.
reference string yes The loan's reference.
relationship_id string (uuid) yes The relationship of the two entities.
lender string yes Code of the lending entity.
borrower string yes Code of the borrowing entity.
currency string yes Currency of the loan.
facility_amount string yes What may be drawn at most.
interest_rate_percent string yes Fixed annual rate in percent.
interest_basis string yes The arm's-length basis the approvers accepted.
day_count "30/360" | "act/360" | "act/365" yes The day count of the interest.
start_date string (date) yes First day a drawdown may be dated.
maturity_date string (date) yes The day it falls due.
lender_bank_account string yes The lender's bank account code.
lender_bank_balance string yes The book balance of the lender's bank account (its posted entries) in the currency it holds (lender_bank_currency): where that is the loan's, a drawdown above it takes the account below zero in the books.
lender_bank_currency string The currency the lender's bank account holds (its own, or the lender's functional currency). (default "")
borrower_bank_account string yes The borrower's bank account code.
net_investment boolean yes Part of the net investment (IAS 21.15).
status "active" | "closed" | "draft" yes draft (waits for a second person), active or closed (repaid in full).
principal string yes Principal outstanding: the drawdowns less the repayments recorded.
accrued_through string (date) or null yes The last day interest has been accrued for; null before the first accrual.
interest_open string yes Interest accrued and not settled yet, in the loan's currency.
requested_by object yes Who asked for it, as an actor object.
approved_by object or null yes Who approved it; null while draft.
approved_at string (date-time) or null yes When it was approved (UTC).
approval_id string (uuid) or null yes The approval request that waits (POST /v1/approvals/{id}/approve).
closed_at string (date-time) or null yes When it was repaid in full (UTC).
created_at string (date-time) yes When it was requested (UTC).

MovementInput

Field Type Required Description
value_date string (date) yes The day the money moves; both entries are dated it.
amount decimal string yes In the loan's currency (a decimal string). (greater than 0)
reference string or null Your reference, e.g. the bank's; optional. (max length 200)

MovementOut

Field Type Required Description
id string (uuid) yes Id of the movement.
kind "dividend_declared" | "interest_accrual" | "loan_drawdown" | "loan_repayment" | "settlement" yes What moved.
relationship_id string (uuid) yes The relationship of the two entities.
loan_id string (uuid) or null yes The loan; null for a dividend.
loan_reference string or null yes The loan's reference.
value_date string (date) yes The day of the movement.
amount string yes In currency.
currency string yes Currency of the movement.
reference string yes Reference.
creditor EntryRef yes The lender's entry (the shareholder's for a dividend).
debtor EntryRef yes The borrower's entry (the declaring entity's for a dividend).
settles_id string (uuid) or null yes What a settlement settles.
detail object yes For interest: from, through and the segments (principal and days); for a repayment or settlement the realised exchange differences.
created_by object yes Who recorded it, as an actor object.
created_at string (date-time) yes When (UTC).
warnings array of string What to know that did not stop it, when it was recorded, in English: that it takes the paying bank account below zero in the books on the value date (the lender's for a drawdown, the borrower's for a repayment or a settlement).
warning_reasons array of Reason The same by code (bankBalance.warning.overdrawn, with account, entity, balance, after, currency and on; overdrawn_in_transit adds in_transit when payments the bank has not executed yet count towards it), in the order of warnings.

Reconciliation

Field Type Required Description
as_of string (date) yes The day the open items are read as of.
relationships array of RelationshipReconciliation yes One entry per relationship.

RejectInput

Field Type Required Description
reason string yes Why the receiving entity refuses the document; the sender sees it. (min length 3; max length 1000)

RelationshipInput

Field Type Required Description
mirror_mode "draft" | "post" draft (default): the document made in the counterpart is a draft that a person there accepts. post: the system posts it at once under the system policy, a standing flow the approval authorises (a monthly management fee); never the default. (default "draft")
tolerance_amount decimal string The difference the reconciliation counts as agreed: rounding only, in tolerance_currency. Default 1.00. (min 0; default "1")
tolerance_currency string or null ISO 4217 currency of the tolerance. Default: the functional currency of entity_a as named in the request. (pattern ^[A-Z]{3}$)
vat_group "ch_vat_group" | "de_organschaft" | "none" none (default), ch_vat_group (a Swiss VAT group, Art. 13 MWSTG: two Swiss entities) or de_organschaft (a German tax group, § 2 para. 2 no. 2 UStG: two German entities). From vat_group_from the supplies between the two are outside the scope of VAT (vat_scope outside, reason vat_group or organschaft) and no VAT report or return has them. Never between a Swiss and a German entity. (default "none")
vat_group_from string (date) or null The date from which the VAT group applies (a Swiss group starts at the beginning of a tax period, Art. 13 para. 2 MWSTG); required with a VAT group, refused without one. Documents dated before it carry VAT as usual.
vat_group_reference string or null The registration or documentation of the group (a notice of the tax authority, the Organträger's confirmation); required with a VAT group. (max length 500)
pricing_method "cost_plus" | "cup" | "other" | "profit_split" | "resale_price" | "tnmm" yes The transfer-pricing method the approvers accepted: cup (comparable uncontrolled price), resale_price, cost_plus, tnmm (transactional net margin), profit_split or other. The system records it and never judges a price.
markup_percent decimal string or null The mark-up in percent where the method has one; required for cost_plus. (min 0; max 1000)
pricing_basis string yes The basis in words: the benchmark or study and its date. Mandatory: an approval without it is refused (§ 1 para. 1 AStG, OECD Model Convention Art. 9). (min length 3; max length 2000)
pricing_documented_on string (date) yes The date the documentation of the prices was made (§ 90 para. 3 AO).
entity_a string yes Code (or id) of one entity of the pair, e.g. CH01.
entity_b string yes Code (or id) of the other entity, e.g. DE01.

RelationshipOut

Field Type Required Description
id string (uuid) yes Id of the relationship.
entity_a string yes Code of the entity whose id sorts first.
entity_b string yes Code of the other entity.
entity_a_name string yes Name of entity_a.
entity_b_name string yes Name of entity_b.
status "active" | "pending" | "suspended" yes pending (waits for a second person's approval), active or suspended.
mirror_mode "draft" | "post" yes draft or post.
tolerance_amount string yes Difference counted as agreed.
tolerance_currency string yes Currency of the tolerance.
vat_group "ch_vat_group" | "de_organschaft" | "none" yes none, ch_vat_group or de_organschaft.
vat_group_from string (date) or null yes From when the VAT group applies.
vat_group_reference string or null yes Registration or documentation.
pricing_method "cost_plus" | "cup" | "other" | "profit_split" | "resale_price" | "tnmm" yes The transfer-pricing method.
markup_percent string or null yes The mark-up, where the method has one.
pricing_basis string yes The basis the approvers accepted.
pricing_documented_on string (date) yes Date of the documentation.
terms_digest string yes SHA-256 of the pair and the terms the approval authorised.
requested_by object yes Who asked for the terms in force.
approved_by object or null yes Who approved them; null while pending.
approved_at string (date-time) or null yes When (UTC).
suspended_by object or null yes Who suspended it, if suspended.
suspended_at string (date-time) or null yes When it was suspended (UTC).
suspend_reason string or null yes Why it was suspended.
created_at string (date-time) yes When the relationship was requested (UTC).
approval_id string (uuid) or null yes The approval request waiting for a second person (the first approval, a change of terms or a resumption): POST /v1/approvals/{approval_id}/approve, not by the person who asked. Null when nothing waits.
pending_terms object or null yes The terms a waiting change would put in force; null when none waits or the request is the first approval.
parties array of GroupPartyOut yes The four customer and vendor records the approval created, two in each entity; empty until approved.
open_mirrors integer yes Mirror documents of this relationship waiting as drafts to be accepted; GET /v1/ic/links?relationship={id}&status=drafted lists them.
not_made integer yes Links whose counterpart could not be made yet (pending; their error says why): GET /v1/ic/links?relationship={id}&status=pending lists them.
rejected_mirrors integer yes Links whose mirror the receiving entity rejected: GET /v1/ic/links?relationship={id}&status=rejected lists them.

RelationshipReconciliation

Field Type Required Description
relationship_id string (uuid) yes The relationship.
entity_a string yes Code of the first entity.
entity_b string yes Code of the second entity.
status "fail" | "n/a" | "pass" | "warn" yes pass (the items add up to the tolerance or less), warn (what differs is entirely listed timing items), fail (a part is unexplained) or n/a (the relationship is not active).
tolerance_amount string yes The tolerance of the relationship.
tolerance_currency string yes Its currency.
difference_in_tolerance_currency string or null yes The sum of the differences of all items, each converted at the ECB closing rate of the day, in tolerance_currency (absolute values); null when a rate is missing. The tolerance is applied to this figure.
unexplained_in_tolerance_currency string or null yes The same for the unexplained items only.
currencies array of CurrencyRow yes The open items per document currency.
items array of ItemRow yes Every link with something open on either side and every group document nobody linked, each with its reason (null where the two sides agree); a link settled in full on both sides is left out. The differences of the items add up to difference of the currency rows.
balances array of BalanceRow The loans, their accrued interest and the declared group dividends between the two, each with what both sides hold of it in its currency; their differences count with the items' towards the tolerance.
carrying array of CarryingRow yes The carrying amounts of the two entities in their functional currencies.
detail string yes The result in words.

RelationshipUpdate

A change to a relationship: new terms (a new approval request), a suspension or the re-activation of a suspended relationship (a request), or a refresh of the group parties.

Field Type Required Description
status "active" | "suspended" or null suspended stops new intercompany postings at once (one person, with a reason); open items stay and settle normally. active on a suspended relationship asks a second person to approve resuming.
mirror_mode "draft" | "post" or null New mirror mode.
tolerance_amount decimal string or null New tolerance. (min 0)
tolerance_currency string or null New tolerance currency. (pattern ^[A-Z]{3}$)
vat_group "ch_vat_group" | "de_organschaft" | "none" or null New VAT group.
vat_group_from string (date) or null New VAT group start date.
vat_group_reference string or null New VAT group reference. (max length 500)
pricing_method "cost_plus" | "cup" | "other" | "profit_split" | "resale_price" | "tnmm" or null New method.
markup_percent decimal string or null New mark-up. (min 0; max 1000)
pricing_basis string or null New pricing basis. (min length 3; max length 2000)
pricing_documented_on string (date) or null New date of the documentation.
refresh_parties boolean Read the name, address, VAT number, country and bank accounts of the two entities again into their four customer and vendor records, which are not edited by hand. Alone: it changes no terms. (default false)
reason string or null Why: required to suspend, kept with a change of terms in the audit trail. (min length 3; max length 1000)

SettlementInput

Field Type Required Description
loan string (uuid) or null Settle the loan's accrued interest; or name a dividend.
dividend string (uuid) or null Settle a declared group dividend: the id of its dividend_declared movement.
value_date string (date) yes The day of the payment.
amount decimal string yes In the currency of what is settled; at most what is open. (greater than 0)
payer_bank_account string or null The paying entity's bank account code; default the loan's (for a dividend the account with the role bank).
payee_bank_account string or null The receiving entity's bank account code; default as above.
reference string or null Your reference. (max length 200)
Stabiso, the Enterprise System of Record · generated from the code and its guides · release 6f03a5e846b3