Skip to content

OpenProject#

OpenProject is registered for bounded, read-only work-package sync from one OpenProject Cloud instance. Each TeamBoost organization stores one API-token credential with an explicit project-id allowlist. Sync produces a reviewable TeamBoost import session; it does not create or change OpenProject work packages or TeamBoost tasks.

Capability Method Status
SYNC Pull selected projects and their work packages through API v3 Built
USER_IMPORT Bring task-linked actors into the proposed user mapping Built as part of API sync
CSV_IMPORT Upload an OpenProject work-package export Not built
WEBHOOK Receive signed OpenProject work-package events Not built

The endpoints below live under /api/v1/providers/openproject/.... They are the generic provider endpoints and require an organization-scoped user token; see Authentication.

Discovery#

GET /api/v1/providers/openproject
{
  "status": "success",
  "data": {
    "provider": "openproject",
    "capabilities": ["SYNC", "USER_IMPORT"]
  }
}

Cloud setup and credential verification#

Create a dedicated OpenProject API token whose user can view work packages in every selected project. Store one strict, versioned credential envelope per TeamBoost organization:

PUT  /api/v1/providers/openproject/credentials?organization_id=<id>
POST /api/v1/providers/openproject/credentials/verify?organization_id=<id>

The write-only outer request contains a JSON-serialized secret:

{
  "secret": "{\"version\":1,\"baseUrl\":\"https://YOUR_TENANT.openproject.com\",\"apiToken\":\"YOUR_API_TOKEN\",\"projectIds\":[17,23]}"
}

The inner envelope accepts exactly version, baseUrl, apiToken, and projectIds:

  • version must be 1.
  • baseUrl must be the HTTPS root of one *.openproject.com Cloud tenant. Arbitrary/self-hosted origins, IP addresses, credentials in the URL, ports, redirects, paths, query strings, and fragments are rejected.
  • apiToken must be one non-empty token without whitespace or control characters.
  • projectIds must be a non-empty, unique list of positive numeric OpenProject project ids. At most 100 ids are accepted.

Verification makes bounded, read-only GET probes for installation metadata, the authenticated API root, each selected project, and one work-package page. Malformed or provider-rejected credentials return invalid_api_key; insufficient project permission returns insufficient_permissions; rejected instance/project inputs return bad_request; transient, DNS, retry-budget, or response-contract failures return service_unavailable.

Stored credentials are encrypted at rest, scoped to one TeamBoost organization, replaceable through the same PUT, and never returned by the API. Status and deletion use the generic GET and DELETE credential routes.

Importing work packages#

POST /api/v1/providers/openproject/imports/sync?organization_id=<id>

The adapter uses fixed-path API v3 GET requests. It reads installation metadata, the authenticated root, selected projects, the complete status/type/ priority reference collections, selected work packages, and unique linked user actors. Work packages are ordered by numeric id, fetched in pages of 50, and limited to 500 per session. Duplicate, repeated, incomplete, inconsistent, or over-limit pagination fails rather than persisting a partial import.

The client resolves the allowlisted Cloud hostname before every attempt, refuses private/link-local/loopback results, never follows redirects, and uses at most three attempts for network, 429, and 5xx failures with a bounded total wait. The API token is sent only as a Bearer token and is never logged or returned.

Each successful work package retains an aligned, snake-cased source record plus a normalized task and proposed TeamBoost draft. Malformed rows are isolated as row errors without shifting task/source alignment.

User mapping#

USER_IMPORT rides work-package sync; there is no standalone user-import route. The adapter fetches each unique linked Author, Assignee, or Responsible user once per session. OpenProject numeric user id is the stable account key. Visible e-mail and display name are matching hints; hidden e-mail is valid.

OpenProject can assign work to groups and placeholder users. Those principals remain sanitized provider context and do not become false TeamBoost users:

  • a mapped real-user Assignee becomes proposed ownerId;
  • a present but unmapped real-user Assignee creates a blocking projection error;
  • an unassigned, group-assigned, or placeholder-assigned task keeps ownerId unset, with non-user principals called out in mapping notes;
  • a mapped Author becomes creatorId; an absent or unmapped Author leaves it unset with a note; and
  • Responsible remains provider context and never becomes requestedById.

Projection field coverage#

OpenProject source TeamBoost draft Behavior
Namespaced work-package id / displayId provider id / identifier Stable instance-scoped identity; invalid identity blocks projection
subject title Fewer than two usable characters blocks projection
Milestone structural flag type Milestones → RELEASE
Type name type Bug/Defect, Feature/User Story, Documentation, Review, Refactor, Performance, and Security map directly; custom values → OTHER plus note
Status and structural closed flag status Canceled → CANCELED; closed → COMPLETED; blocked/hold → BLOCKED; active → IN_PROGRESS; open/backlog/custom fallback → NOT_STARTED, with notes for conservative reduction
Priority priority Urgent/High/Medium/Low map directly; custom values → UNKNOWN plus note
Category labels Non-empty category title becomes a label
Project name projectTitle Preserved as the provider project name
Actor mappings creatorId, ownerId Resolved through the session mapping as described above
Import lifecycle scheduleStage Defaults to PENDING
Date-only scheduling, duration, progress, version, hierarchy, relation availability, custom fields, provider timestamps, and stable actor ids descriptionJson.openproject Curated context only; no unsupported TeamBoost scheduling, release, or dependency value is invented

The projected provider context excludes actor e-mail/name fields, credentials, raw description variants, and HTML. The normalized plain-text description is used as description.

Not built yet#

  • OpenProject self-hosted or arbitrary instance origins.
  • CSV import.
  • OAuth application installation and token refresh.
  • Standalone/full-directory user import.
  • Webhook ingress, signature verification, replay protection, or event processing.
  • Incremental sync state or work-package write-back.
  • Mapping date-only fields, duration, progress, versions, hierarchy, or relations into TeamBoost scheduling, releases, or dependencies.