generated: '2026-09-06' method: searched source: >- openapi/_original/apiman-openapi.json, https://www.apiman.io/apiman-docs/user-guide/latest/manager/data-model.html, https://www.apiman.io/apiman-docs/user-guide/latest/manager/versioning.html, https://www.apiman.io/apiman-docs/installation-guide/latest/keycloak.html cross_links: authentication: authentication/apiman-authentication.yml errors: errors/apiman-problem-types.yml lifecycle: lifecycle/apiman-lifecycle.yml rate_limits: rate-limits/apiman-rate-limits.yml data_model: data-model/apiman-data-model.yml base_url: form: "https://{apiman_host}/apiman" note: >- Apiman is self-hosted; there is no vendor-operated host. The OpenAPI servers[] value is the relative path /apiman, and the documented default in the project's own changelog is http://localhost:8080/apiman. The Docker Compose quickstart binds http://apiman.local.gd:8080/apiman. authentication: style: OIDC bearer token issued by the operator's Keycloak (Manager API); HTTP BASIC + apipublisher role (Gateway API) in_spec: false note: The published OpenAPI declares no securitySchemes; see authentication/apiman-authentication.yml. idempotency: supported: false coverage: none header: null scope: [] retention: null evidence: >- No Idempotency-Key header, no idempotency parameter, and no replay-protection language appears anywhere in the 177-operation OpenAPI or in the user, installation or development guides. Retrying a POST such as createOrg, createApi, createContract or performAction is not safe: creates answer 409 on a duplicate version but there is no request-key mechanism that would let an agent distinguish "my retry landed twice" from "someone else created it". mitigations: - >- Entity creates are addressed by a caller-chosen id (organizationId, apiId, version), so a duplicate create fails 409 rather than silently creating a second entity. This is natural-key deduplication, not idempotency, and it does not cover PUT/DELETE or performAction. - PUT updates (updateApi, updateOrg, updatePlan, updateClientPolicy) are idempotent by HTTP semantics. reversibility: grade: documented note: >- Apiman has a real, first-class reversal surface — every publish/register lifecycle transition has a named inverse exposed through performAction (ActionBean.type enum: publishAPI, retireAPI, registerClient, unregisterClient, lockPlan) — but the docs state no time window for any of them, so this grades `documented`, not `verified`. No window is asserted here, because none is published. reversals: - action: Publish an API version to a gateway operation: performAction action_type: publishAPI reversal: performAction with type retireAPI window: null window_source: null note: >- Retiring removes the API from the gateway. The changelog records that as of 3.1.2.Final an organization with retired entities can be deleted, which was previously blocked. - action: Register a client app version with a gateway operation: performAction action_type: registerClient reversal: performAction with type unregisterClient window: null - action: Lock a plan version operation: performAction action_type: lockPlan reversal: none window: null note: >- IRREVERSIBLE BY DESIGN. "Once a plan has been fully configured it must be locked so that it can be used by APIs. This is done so that API providers can't change the details of the plan out from underneath the client app developers who are using it." The forward path is to create a new plan version, not to unlock. - action: Create an API contract (client subscribes to an API through a plan) operation: createContract reversal: deleteContract ("Break Contract"), or deleteAllContracts ("Break All Contracts") window: null - action: Approve a pending contract operation: approveContract reversal: deleteContract window: null - action: Grant organization membership operation: grant reversal: revoke (single role) or revokeAll (all memberships for a user) window: null - action: Rotate a client API key operation: updateClientApiKey reversal: none window: null note: The previous key is not recoverable; supply the desired key explicitly to control the value. - action: Delete an organization, API, client or plan operation: deleteOrg / deleteApi / deleteClient / deletePlan reversal: none window: null note: >- Destructive and unrecoverable through the API. The only restore path is an out-of-band data restore, or a full-system re-import via importData from a prior exportData snapshot (GET /system/export, POST /system/import) — a whole-instance operation, not a per-entity undo. - action: Freeze an entity by publishing or locking it operation: performAction reversal: createApiVersion / createClientVersion / createPlanVersion window: null note: >- Versioning is Apiman's general rollback mechanism: a frozen entity cannot be edited, so the documented way back is a new version, optionally cloned from the existing one. Public APIs and Client Apps are the exception and may be edited and re-published in place. system_level: export: exportData (GET /system/export) import: importData (POST /system/import) note: The only whole-instance backup/restore path, documented under manager/backup-migration. dry_run_mode: supported: partial operations: - operation: test path: PUT /gateways description: Test a gateway configuration before creating it — a genuine rehearsal call. - operation: probeContractPolicy path: POST /organizations/{organizationId}/clients/{clientId}/versions/{version}/contracts/{contractId}/policies/{policyId} description: Probe a policy attached to a contract to inspect its runtime state without modifying it. - operation: getApiPolicyChain description: Inspect the resolved policy chain for an API version under a plan before publishing. note: No general dry-run flag exists on write operations. pagination: style: page-number applies_to: the /search/* and /devportal/search/* operations and getNotificationsForUser request: body_object: SearchCriteriaBean fields: paging: "PagingBean { page: int32, pageSize: int32 }" order_by: "OrderByBean { name: string, ascending: bool }" filters: "SearchCriteriaFilterBean[] { name, value, operator }" operators: [bool_eq, eq, neq, gt, gte, lt, lte, like] response: envelope: "SearchResultsBean (SearchResultsBeanApiSummaryBean, SearchResultsBeanOrganizationSummaryBean, SearchResultsBeanClientSummaryBean, SearchResultsBeanRoleBean, SearchResultsBeanAuditEntryBean, SearchResultsBeanUserSearchResult, SearchResultsBeanAvailableApiBean, SearchResultsBeanNotificationDtoObject)" note: >- Searches are POST-with-body, not GET-with-query-params, so they are not cacheable and not linkable. List endpoints outside /search (listApis, listClients, listPlans, listMembers, getOrganizations) take no paging parameters at all and return the full collection. no_cursor: true no_link_header: true filtering_and_sorting: filters: SearchCriteriaFilterBean (name/value/operator) inside the search body sorting: OrderByBean (name, ascending) inside the search body expansion: none sparse_fieldsets: none note: >- Apiman instead ships hand-built *SummaryBean / *Dto projections (ApiSummaryBean, ClientSummaryBean, PlanSummaryBean, ApiVersionSummaryBean, PolicySummaryBean…) — the list shape is fixed by the server, not chosen by the caller. metadata: user_defined: >- APIs carry arbitrary key/value tags (ApiBean.tags, KeyValueTag / KeyValueTagDto), set with tagApi (PUT /organizations/{organizationId}/apis/{apiId}/tags). audit: >- Every entity exposes an activity trail of AuditEntryBean (who, entityType, entityId, entityVersion, createdOn, what, data): getOrgActivity, getApiActivity, getApiVersionActivity, getClientActivity, getClientVersionActivity, getPlanActivity, getPlanVersionActivity, getActivity (per user). provenance_fields: [createdBy, createdOn, modifiedBy, modifiedOn, publishedOn, retiredOn, lockedOn, joinedOn] request_tracing: request_id_header: null note: No correlation/request-id header is documented or declared in the spec. The audit trail is the after-the-fact substitute. versioning: api_surface: >- Unversioned URI. The whole Manager API is served under the deployment context path /apiman and moves with the product release (current 3.1.3.Final). There is no /v1, no version header and no version query parameter. entities: >- Plans, APIs and Client Apps are independently versioned first-class objects. Frozen once Locked or Published; a new version (optionally cloned) is the documented way to change a frozen entity. docs: https://www.apiman.io/apiman-docs/user-guide/latest/manager/versioning.html error_envelope: declared: false note: See errors/apiman-problem-types.yml — no error schema is bound to any 4xx in the spec. rate_limit_signaling: on_this_api: none note: >- The Manager REST API publishes no rate limits and returns no RateLimit-* headers. Apiman's rate-limiting, quota and transfer-quota POLICIES are a gateway feature applied to managed third-party traffic. See rate-limits/apiman-rate-limits.yml. content_types: request: [application/json, multipart/form-data (uploadBlob)] response: [application/json, application/x-yaml, application/wsdl+xml] note: >- getApiDefinition returns the managed API's own definition document, which is why application/wsdl+xml and application/x-yaml appear in Apiman's contract — Apiman stores and serves other people's specs, including WSDL.