Visena Documentation
Partner API

Resource

Project

Projects — the unit of work companies and activities hang off. Full CRUD; create requires a templateId, and delete closes the project instead of destroying it.

In origo terms a project is an engagement — the unit of work a customer engages the firm for. It belongs to a company, it is owned by a group, and activities hang off it; it is not a software project. projectType names the two shapes an engagement takes, PROJECT_TYPE_PROJECT and PROJECT_TYPE_ASSIGNMENT.

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

Eight 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 project

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

Creates a project from a template and returns the full entity. 201 with a Location header.

Request body

application/jsonProjectCreateDto

Responses

Status Description
201 Project created.
ProjectResponseDto · application/json
400 Request body failed validation.
422 A referenced entity (template, company, ownerGroup, parent, responsible, createdBy, modifiedBy) does not exist.

Example

curl
curl -X POST "https://api.visena.example/acme/api/v1/en/project" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Warehouse rollout",
    "templateId": "tM2qL6",
    "ownerGroupId": "gH8dF3",
    "companyId": "bQ4wR8"
  }'

Get a project

GET /{instanceName}/api/v1/{locale}/project/{projectId}

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

Parameters

Parameter In Type Description
projectId required path string Masked project id.

Responses

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

Example

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

List projects (offset-paginated)

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

Offset/limit paging with a real total. Optional filters: isActive, companyId; and a created/modified/name sort. RFC 8288 navigation links are in the body.

Parameters

Parameter In Type Description
offset query integer
default 0
Zero-based item offset.
limit query integer Maximum items to return per page.
isActive query boolean Filter on active state.
companyId query string Masked company id.
sort query string Sort key; the endpoint description lists the allowed values.

Responses

Status Description
200 A page of projects with totals and navigation links.
ProjectOffsetListResponse · application/json
400 Invalid paging or sort parameter, or a filter id is not a valid id.

Example

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

List projects (cursor-paginated, insert-stable)

GET /{instanceName}/api/v1/{locale}/project/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. Same filters as the offset list: isActive, companyId.

Cursor paging and the timeline below are two different read modes, not two page shapes. Which one suits a single-pass extract, which one you resume from, whether a row can arrive twice, and what a list response says when a project disappears are all settled once for the whole API in Lists, paging and sync — read it before you build a synchronisation loop on this endpoint or on listProjectsByTime.

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.
isActive query boolean Filter on active state.
companyId query string Masked company id.

Responses

Status Description
200 A page of projects with next/prev cursors and links.
ProjectCursorListResponse · application/json
400 Invalid or expired cursor, or invalid limit.

Example

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

List projects (time-windowed, cursor-paginated)

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

Keyset paging from an optional since lower bound on the coalesced modified-or-created timestamp. RFC 9557 Z timestamps.

Parameters

Parameter In Type Description
since query string (date-time) Inclusive lower bound — an RFC 3339 timestamp.
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.

Responses

Status Description
200 A page of projects with next/prev cursors and links.
ProjectCursorListResponse · application/json
400 Invalid timestamp, cursor, or limit.

Example

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

Replace a project

PUT /{instanceName}/api/v1/{locale}/project/{projectId}

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

Parameters

Parameter In Type Description
projectId required path string Masked project id.

Request body

application/jsonProjectUpdateDto

Responses

Status Description
200 The replaced project.
ProjectResponseDto · application/json
400 Request body failed validation, or the id is not a valid id.
404 No project with that id.
422 A referenced entity (template, company, ownerGroup, parent, responsible, modifiedBy) does not exist.

Example

curl
curl -X PUT "https://api.visena.example/acme/api/v1/en/project/pJ7wN2" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Warehouse rollout",
    "templateId": "tM2qL6",
    "ownerGroupId": "gH8dF3",
    "companyId": "bQ4wR8"
  }'

Partially update a project (RFC 7396 JSON Merge Patch)

PATCH /{instanceName}/api/v1/{locale}/project/{projectId}

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
projectId required path string Masked project id.

Request body

application/merge-patch+jsonobject

Responses

Status Description
200 The updated project.
ProjectResponseDto · application/json
400 A patched field had an invalid value, or the id is not a valid id.
404 No project with that id.
415 Content-Type was not application/merge-patch+json.
422 A referenced entity (template, company, ownerGroup, parent, responsible, modifiedBy) does not exist.

Example

curl
curl -X PATCH "https://api.visena.example/acme/api/v1/en/project/pJ7wN2" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/merge-patch+json" \
  -d '{
    "name": "Warehouse rollout — phase 2"
  }'

Delete (close) a project

DELETE /{instanceName}/api/v1/{locale}/project/{projectId}

Soft-close: sets the project inactive through the same flow the Visena UI uses. 204 on success.

Parameters

Parameter In Type Description
projectId required path string Masked project id.

Responses

Status Description
204 Project closed; no body.
400 The id is not a valid id.
404 No project with that id.

Example

curl
curl -X DELETE "https://api.visena.example/acme/api/v1/en/project/pJ7wN2" \
  -H "Authorization: Bearer $TOKEN"

Object shapes

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

ProjectCreateDto

Field Type Description
name required string Project display name. Required.
companyId string (masked id)
templateId required string (masked id)
ownerGroupId required string (masked id)
parentId string (masked id)
responsiblePersonId string (masked id)
projectYear object Project year.
estimatedStart string (date-time) Estimated start (RFC 3339).
estimatedEnd string (date-time) Estimated end (RFC 3339).
projectStart string (date-time) Actual start (RFC 3339). Defaults to the creation timestamp when absent.
projectEnd string (date-time) Actual end (RFC 3339).
externalReference string External reference / foreign system key.
internalReference string Internal reference.
isPublicAccess object Whether the project is visible across the tenant (public access). Defaults from the template.
isChargable object Whether the project is chargeable. Defaults from the template.
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)

ProjectResponseDto

Field Type Description
id string (masked id)
number string Human-readable project number, assigned by Visena.
name string
company CompanyRefDto
template ProjectTemplateRefDto
ownerGroup GroupRefDto
projectYear object Project year, if set.
parentId string (masked id)
responsible string (masked id)
projectType string, one of PROJECT_TYPE_PROJECT PROJECT_TYPE_ASSIGNMENT
estimatedStart string (date-time) Estimated start (UTC), if set.
estimatedEnd string (date-time) Estimated end (UTC), if set.
projectStart string (date-time) Actual start (UTC).
projectEnd string (date-time) Actual end (UTC), if set.
externalReference string
internalReference string
isPublicAccess boolean
isChargable boolean
isActive boolean
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)

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.

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".

ProjectTemplateRefDto

Project template the project was created from.

Field Type Description
id string (masked id)
name string Project template display name.

GroupRefDto

Owning group / department.

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

ProjectOffsetListResponse

Field Type Description
totalItems integer Total number of matching projects.
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 ProjectListItemDto The projects on this page.
links ProjectListLinks

ProjectListItemDto

The projects on this page, in ascending key order.

Field Type Description
id string (masked id)
name string Project display name.
number string Human-readable project number, if assigned.
isActive boolean Whether the project is active.
projectYear object Project year, if set.
projectType string, one of PROJECT_TYPE_PROJECT PROJECT_TYPE_ASSIGNMENT
company CompanyRefDto
ownerGroup GroupRefDto
responsible string (masked id)
projectStart string (date-time) Actual start (UTC).
projectEnd string (date-time) Actual end (UTC), if set.
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).

ProjectCursorListResponse

Field Type Description
items array of ProjectListItemDto The projects on this page, in ascending key order.
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 ProjectListLinks

ProjectUpdateDto

Field Type Description
name required string Project display name. Required.
companyId string (masked id)
templateId required string (masked id)
ownerGroupId required string (masked id)
parentId string (masked id)
responsiblePersonId string (masked id)
projectYear object Project year.
estimatedStart string (date-time) Estimated start (RFC 3339).
estimatedEnd string (date-time) Estimated end (RFC 3339).
projectStart string (date-time) Actual start (RFC 3339). Defaults to the creation timestamp when absent.
projectEnd string (date-time) Actual end (RFC 3339).
externalReference string External reference / foreign system key.
internalReference string Internal reference.
isPublicAccess object Whether the project is visible across the tenant (public access).
isChargable object Whether the project is chargeable.
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)