Visena Documentation
Partner API

Resource

Company

The companies (organisations) the instance works with. Full CRUD and a duplicate probe; an organisation number is unique per instance, and delete deactivates by default.

The endpoint reference below is kept in English in both language trees. It mirrors the API contract verbatim and there is no generator to rebuild it from, so a translated copy would drift from the API the first time an endpoint changes.

Endpoints

Nine endpoints, in the order they are documented below.

Every endpoint on this page can additionally answer the shared errors — 401, 403, 404 (unknown instance) and 500. They are documented once, under Errors and troubleshooting.

Create a company

POST /{instanceName}/api/v1/{locale}/company

Creates a company and returns the full entity. 201 with a Location header.

Request body

application/jsonCompanyCreateDto

Responses

Status Description
201 Company created.
CompanyResponseDto · application/json
400 Request body failed validation.
409 The companyNumber or an organizational number is already used by another company.
422 A referenced entity (createdBy, modifiedBy, parent, ownerGroup, template, responsible, country, invoiceCompany, invoiceRecipient) does not exist.

Example

curl
curl -X POST "https://api.visena.example/acme/api/v1/en/company" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Logistics AS",
    "countryCode": "NO",
    "ownerGroupId": "gH8dF3",
    "organizationalNumbers": [
      {
        "orgNumber": "923609016",
        "countryCode": "NO"
      }
    ]
  }'

Get a company

GET /{instanceName}/api/v1/{locale}/company/{companyId}

Returns the full entity. 404 if unknown; 400 if the id cannot be unmasked.

Parameters

Parameter In Type Description
companyId required path string Masked company id.

Responses

Status Description
200 The company.
CompanyResponseDto · application/json
400 The id is not a valid id.
404 No company with that id.

Example

curl
curl "https://api.visena.example/acme/api/v1/en/company/bQ4wR8" \
  -H "Authorization: Bearer $TOKEN"

List companies (offset-paginated)

GET /{instanceName}/api/v1/{locale}/company

Offset/limit paging with a real total. Optional filters: query (name search), isActive, ownerGroupId, orgNumber (exact active org number), companyNumber (exact), externalReference (exact); and a created/modified/name sort. RFC 8288 navigation links are in the body. view selects the item projection: set view=full to receive, for every row, the same body the per-company read returns (createdBy/modifiedBy and the AML triad included) instead of the lean list item; allowed values are lean and full, the default is lean, and view=full caps limit at 100.

Parameters

Parameter In Type Description
offset query integer
default 0
Zero-based item offset.
limit query integer Maximum items to return per page.
query query string Free-text filter; the endpoint description lists the fields it matches.
isActive query boolean Filter on active state.
ownerGroupId query string Masked owner-group id.
orgNumber query string Exact organisation-number filter.
companyNumber query string Exact company-number filter.
externalReference query string Exact external-reference filter.
sort query string Sort key; the endpoint description lists the allowed values.
view query string, one of lean full
default lean
Item projection: lean (default) for the compact list item, full for the same body the per-company read returns. full caps limit at 100.

Responses

Status Description
200 A page of companies with totals and navigation links.
CompanyOffsetListResponse · application/json
400 Invalid paging or sort parameter, or a filter id is not a valid id.
404 Under view=full, a company on this page no longer exists (permanently removed between the page query and the record read). Retry the request.

Example

curl
curl "https://api.visena.example/acme/api/v1/en/company?offset=0&limit=20" \
  -H "Authorization: Bearer $TOKEN"

List companies (cursor-paginated, insert-stable)

GET /{instanceName}/api/v1/{locale}/company/cursor

Keyset paging over the monotonic entity id (insertion order). Pass the opaque cursor from a previous page's nextCursor/prevCursor; omit it for the first page. No total — keyset skips the count. Same filters as the offset list: query, isActive, ownerGroupId, orgNumber, companyNumber, externalReference. view selects the item projection: set view=full to receive, for every row, the same body the per-company read returns (createdBy/modifiedBy and the AML triad included) instead of the lean list item; allowed values are lean and full, the default is lean, and view=full caps limit at 100.

The offset, cursor and timeline lists are three different read modes. Which one to use for a one-off extract and which one to resume an ongoing synchronisation from, how to de-duplicate what you receive, and what a list response does not tell you about deletions, are documented once for the whole API under Lists, paging and sync. Read it before building a synchronisation on any of them.

Parameters

Parameter In Type Description
cursor query string Opaque page cursor from the previous response's links.next; omit for the first page.
limit query integer Maximum items to return per page.
query query string Free-text filter; the endpoint description lists the fields it matches.
isActive query boolean Filter on active state.
ownerGroupId query string Masked owner-group id.
orgNumber query string Exact organisation-number filter.
companyNumber query string Exact company-number filter.
externalReference query string Exact external-reference filter.
view query string, one of lean full
default lean
Item projection: lean (default) for the compact list item, full for the same body the per-company read returns. full caps limit at 100.

Responses

Status Description
200 A page of companies with next/prev cursors and links.
CompanyCursorListResponse · application/json
400 Invalid or expired cursor, or invalid limit.
404 Under view=full, a company on this page no longer exists (permanently removed between the page query and the record read). Retry the request.

Example

curl
curl "https://api.visena.example/acme/api/v1/en/company/cursor?limit=100" \
  -H "Authorization: Bearer $TOKEN"

List companies (time-windowed, cursor-paginated)

GET /{instanceName}/api/v1/{locale}/company/timeline

Keyset paging from an optional since lower bound on a selectable key (created|modified). RFC 9557 Z timestamps. A cursor minted for a different key is rejected with 400. view selects the item projection: set view=full to receive, for every row, the same body the per-company read returns (createdBy/modifiedBy and the AML triad included) instead of the lean list item; allowed values are lean and full, the default is lean, and view=full caps limit at 100.

Parameters

Parameter In Type Description
since query string (date-time) Inclusive lower bound — an RFC 3339 timestamp.
key query string Which timestamp to page on: created or modified.
cursor query string Opaque page cursor from the previous response's links.next; omit for the first page.
limit query integer Maximum items to return per page.
view query string, one of lean full
default lean
Item projection: lean (default) for the compact list item, full for the same body the per-company read returns. full caps limit at 100.

Responses

Status Description
200 A page of companies with next/prev cursors and links.
CompanyCursorListResponse · application/json
400 Invalid timestamp, key, cursor, or limit.
404 Under view=full, a company on this page no longer exists (permanently removed between the page query and the record read). Retry the request.

Example

curl
curl "https://api.visena.example/acme/api/v1/en/company/timeline?since=2026-08-20T02:00:00Z" \
  -H "Authorization: Bearer $TOKEN"

Search for potential duplicate companies

GET /{instanceName}/api/v1/{locale}/company/duplicates

Duplicate-detection probe for the create flow. Matches by exact organizational number (active numbers only) and/or exact companyNumber — the same identifiers the create/update 409 guard checks, so a hit here predicts that conflict and shows the holding company when the caller is allowed to see it. At least one of orgNumber or companyNumber is required. Org-number matches are listed first; results are capped by limit (default 20; values above 100 are clamped to 100).

Parameters

Parameter In Type Description
orgNumber query string Exact organisation-number filter.
companyNumber query string Exact company-number filter.
limit query integer Maximum items to return per page.

Responses

Status Description
200 The potential duplicates (empty when none match).
CompanyDuplicateListResponse · application/json
400 No search signal (orgNumber/companyNumber both absent) or a limit below 1.

Example

curl
curl "https://api.visena.example/acme/api/v1/en/company/duplicates?orgNumber=923609016" \
  -H "Authorization: Bearer $TOKEN"

Replace a company

PUT /{instanceName}/api/v1/{locale}/company/{companyId}

Full replace (PUT): omitted optional fields are cleared.

Parameters

Parameter In Type Description
companyId required path string Masked company id.

Request body

application/jsonCompanyUpdateDto

Responses

Status Description
200 The replaced company.
CompanyResponseDto · application/json
400 Request body failed validation, or the id is not a valid id.
404 No company with that id.
409 The companyNumber or an organizational number is already used by another company.
422 A referenced entity (modifiedBy, parent, ownerGroup, template, responsible, country, invoiceCompany, invoiceRecipient) does not exist.

Example

curl
curl -X PUT "https://api.visena.example/acme/api/v1/en/company/bQ4wR8" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Logistics AS",
    "countryCode": "NO",
    "ownerGroupId": "gH8dF3",
    "organizationalNumbers": [
      {
        "orgNumber": "923609016",
        "countryCode": "NO"
      }
    ]
  }'

Partially update a company (RFC 7396 JSON Merge Patch)

PATCH /{instanceName}/api/v1/{locale}/company/{companyId}

Absent fields are unchanged, JSON null clears, a value sets. An empty body {} is a no-op. Wrong content type → 415.

Parameters

Parameter In Type Description
companyId required path string Masked company id.

Request body

application/merge-patch+jsonobject

Responses

Status Description
200 The updated company.
CompanyResponseDto · application/json
400 A patched field had an invalid value, or the id is not a valid id.
404 No company with that id.
409 The companyNumber or an organizational number is already used by another company.
415 Content-Type was not application/merge-patch+json.
422 A referenced entity (modifiedBy, parent, ownerGroup, template, responsible, country, invoiceCompany, invoiceRecipient) does not exist.

Example

curl
curl -X PATCH "https://api.visena.example/acme/api/v1/en/company/bQ4wR8" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "externalReference": "ERP-4711",
    "riskValue": "LOW"
  }'

Delete or deactivate a company

DELETE /{instanceName}/api/v1/{locale}/company/{companyId}

mode=deactivate (default) sets the company inactive; mode=delete hard-deletes it. 204 on success; a repeat hard-delete → 404.

Parameters

Parameter In Type Description
companyId required path string Masked company id.
mode query string
default deactivate
Delete mode; the endpoint description explains the options and the default.

Responses

Status Description
204 Company deleted or deactivated; no body.
400 The id is not a valid id, or mode was not deactivate/delete.
404 No company with that id (or already deleted).

Example

curl
curl -X DELETE "https://api.visena.example/acme/api/v1/en/company/bQ4wR8?mode=deactivate" \
  -H "Authorization: Bearer $TOKEN"

Object shapes

The request and response bodies used above, in the order they are first referenced.

CompanyCreateDto

Field Type Description
name required string Company display name. Required.
companyNumber string Internal company number.
externalReference string External reference / foreign system key.
dunsNumber string D-U-N-S number.
mainPhone string Main switchboard phone. Digits, spaces, +, -, ( ) only.
mobilePhone string Mobile phone. Digits, spaces, +, -, ( ) only.
fax string Fax. Digits, spaces, +, -, ( ) only.
email string Company email address.
homePage string Company home page URL.
postAddress string Postal address line 1.
postAddress2 string Postal address line 2.
postZipCode string
postPlace string
postCity string
visitAddress string Visiting address line 1.
visitAddress2 string Visiting address line 2.
visitZipCode string
visitPlace string
visitCity string
isInvoiceAddressOverridden object Whether the invoice address overrides post/visit; when false the invoice address is derived.
invoiceAddress string Invoice address line 1.
invoiceAddress2 string Invoice address line 2.
invoiceZipCode string
invoicePlace string
invoiceCity string
countryCode required string, one of NO SE DK GB CH ISO 3166-1 alpha-2 country code (see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Required. Resolved server-side; unknown → 422.
parentId string (masked id)
ownerGroupId required string (masked id)
templateId string (masked id)
responsiblePersonId string (masked id)
invoiceCompanyId string (masked id)
invoiceRecipientId string (masked id)
invoiceCountryCode string, one of NO SE DK GB CH ISO 3166-1 alpha-2 invoice country code. Resolved server-side; unknown → 422.
isActive object
isPrivate object
isPublicAccess object Whether the company is visible across the tenant (public access).
newProjectsDefaultAccessControlled object Whether new projects on this company default to access-controlled.
riskValue string, one of NOT_ASSESSED LOW MEDIUM HIGH NOT_APPLICABLE
pepValue string, one of NOT_ASSESSED YES YES_EXPIRED NO DONT_KNOW NOT_APPLICABLE
sanctionValue string, one of NOT_ASSESSED YES NO NOT_APPLICABLE
organizationalNumbers array of OrgNumberWriteDto Organizational (registration) number — at most one (Visena keeps a single active number per company); >1 entry is rejected with 400. Empty or omitted sets none.
created string (date-time) override: creation timestamp to attribute. Defaults to server-now (UTC) when absent.
createdBy string (masked id)
modified string (date-time) override: modification timestamp (set alongside creation when provided).
modifiedBy string (masked id)

OrgNumberWriteDto

Organizational (registration) number — at most one (Visena keeps a single active number per company); >1 entry is rejected with 400. Full replace: omitted or empty clears it.

Field Type Description
orgNumber required string The organizational (registration) number. Validated per country (Norway: 9 digits, mod-11 checksum); an invalid number is rejected 400.
countryCode required string ISO 3166-1 alpha-2 country code the number is registered in, e.g. "NO". Resolved server-side; unknown → 422.

CompanyResponseDto

Field Type Description
id string (masked id)
name string
companyNumber string
externalReference string
dunsNumber string
organizationalNumbers array of OrgNumberDto Active organizational (registration) numbers; at most one per company.
mainPhone string
mobilePhone string
fax string
email string
homePage string
postAddress string
postAddress2 string
postZipCode string
postPlace string
postCity string
visitAddress string
visitAddress2 string
visitZipCode string
visitPlace string
visitCity string
isInvoiceAddressOverridden boolean
invoiceAddress string
invoiceAddress2 string
invoiceZipCode string
invoicePlace string
invoiceCity string
country CountryRefDto
invoiceCountry CountryRefDto
parent CompanyRefDto
invoiceCompany CompanyRefDto
ownerGroup GroupRefDto
responsible string (masked id)
invoiceRecipientId string (masked id)
templateId string (masked id)
isActive boolean
isPrivate boolean
isPublicAccess boolean
newProjectsDefaultAccessControlled boolean
riskValue string, one of NOT_ASSESSED LOW MEDIUM HIGH NOT_APPLICABLE
pepValue string, one of NOT_ASSESSED YES YES_EXPIRED NO DONT_KNOW NOT_APPLICABLE
sanctionValue string, one of NOT_ASSESSED YES NO NOT_APPLICABLE
created string (date-time) Creation timestamp (UTC).
createdBy string (masked id)
modified string (date-time) Last-modification timestamp (UTC); null until first modified.
modifiedBy string (masked id)
actedBy string (masked id)

OrgNumberDto

Active organizational (registration) numbers; at most one per company.

Field Type Description
orgNumber string The organizational (registration) number.
country CountryRefDto

CountryRefDto

Country this organizational number is registered in.

Field Type Description
id string (masked id)
name string Country display name.
code string ISO 3166-1 alpha-2 country code, e.g. "NO".

CompanyRefDto

The company the owning project belongs to, if any.

Field Type Description
id string (masked id)
name string Company display name.
organizationalNumbers array of OrgNumberDto Active organizational (registration) numbers; at most one per company.

GroupRefDto

Owning group / department.

Field Type Description
id string (masked id)
name string Group display name.

CompanyOffsetListResponse

Field Type Description
totalItems integer Total number of matching companies.
totalPages integer Total number of pages at the current page size.
page integer Zero-based index of the current page.
size object Page size actually applied.
items array of CompanyListItem The companies on this page, in the projection selected by view.
links CompanyListLinks

CompanyListItem

A company as returned by a list operation. Which of the two shapes is returned is chosen by the view query parameter: lean (the default) yields the compact list item, full yields the same body the per-company read returns.

No fields of its own: the shape is either CompanyListItemDto (view=lean) or CompanyResponseDto (view=full).

CompanyListItemDto

Field Type Description
id string (masked id)
name string Company display name.
organizationalNumbers array of OrgNumberDto Organizational (registration) numbers. The list endpoint carries the company's single active number.
companyNumber string Internal company number, if any.
mainPhone string Main switchboard phone.
email string Company email address.
country CountryRefDto
ownerGroup GroupRefDto
isActive boolean Whether the company is active.
isPrivate boolean Whether the company is private.
riskValue string, one of NOT_ASSESSED LOW MEDIUM HIGH NOT_APPLICABLE
pepValue string, one of NOT_ASSESSED YES YES_EXPIRED NO DONT_KNOW NOT_APPLICABLE
sanctionValue string, one of NOT_ASSESSED YES NO NOT_APPLICABLE
created string (date-time) Creation timestamp (UTC).
modified string (date-time) Last-modification timestamp (UTC); null until first modified.

RFC 8288 navigation links.

Field Type Description
self string URL of the current page.
first string URL of the first page (offset endpoint).
prev string URL of the previous page, if any.
next string URL of the next page, if any.
last string URL of the last page (offset endpoint).

CompanyCursorListResponse

Field Type Description
items array of CompanyListItem The companies on this page, in ascending key order, in the projection selected by view.
nextCursor string Opaque cursor for the next page; absent on the last page.
prevCursor string Opaque cursor for the previous page; absent on the first page.
links CompanyListLinks

CompanyDuplicateListResponse

Field Type Description
items array of CompanyListItemDto Potential duplicate companies, org-number matches before companyNumber matches.

CompanyUpdateDto

Field Type Description
name required string Company display name. Required.
companyNumber string Internal company number.
externalReference string External reference / foreign system key.
dunsNumber string D-U-N-S number.
mainPhone string Main switchboard phone. Digits, spaces, +, -, ( ) only.
mobilePhone string Mobile phone. Digits, spaces, +, -, ( ) only.
fax string Fax. Digits, spaces, +, -, ( ) only.
email string Company email address.
homePage string Company home page URL.
postAddress string Postal address line 1.
postAddress2 string Postal address line 2.
postZipCode string
postPlace string
postCity string
visitAddress string Visiting address line 1.
visitAddress2 string Visiting address line 2.
visitZipCode string
visitPlace string
visitCity string
isInvoiceAddressOverridden object Whether the invoice address overrides post/visit; when false the invoice address is derived.
invoiceAddress string Invoice address line 1.
invoiceAddress2 string Invoice address line 2.
invoiceZipCode string
invoicePlace string
invoiceCity string
countryCode required string, one of NO SE DK GB CH ISO 3166-1 alpha-2 country code (see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Required. Resolved server-side; unknown → 422.
parentId string (masked id)
ownerGroupId required string (masked id)
templateId string (masked id)
responsiblePersonId string (masked id)
invoiceCompanyId string (masked id)
invoiceRecipientId string (masked id)
invoiceCountryCode string, one of NO SE DK GB CH ISO 3166-1 alpha-2 invoice country code. Resolved server-side; unknown → 422.
isActive object
isPrivate object
isPublicAccess object Whether the company is visible across the tenant (public access).
newProjectsDefaultAccessControlled object Whether new projects on this company default to access-controlled.
riskValue string, one of NOT_ASSESSED LOW MEDIUM HIGH NOT_APPLICABLE
pepValue string, one of NOT_ASSESSED YES YES_EXPIRED NO DONT_KNOW NOT_APPLICABLE
sanctionValue string, one of NOT_ASSESSED YES NO NOT_APPLICABLE
organizationalNumbers array of OrgNumberWriteDto Organizational (registration) number — at most one (Visena keeps a single active number per company); >1 entry is rejected with 400. Full replace: omitted or empty clears it.
created string (date-time) Audit override: creation timestamp. Immutable on update — ignored.
createdBy string (masked id)
modified string (date-time) Audit override: modification timestamp to attribute. Defaults to server-now (UTC) when absent.
modifiedBy string (masked id)