Skip to content

Open Discover

Overview

The Open Discover Service API (open-api-disc) lets a client retrieve the Service APIs currently published at the CCF, filtered by a range of optional criteria.

It is called "Open" because, unlike the regular Discover Service API, it does not require the caller to be an onboarded API Invoker. OpenCAPIF still requires a bearer token to call it (see Authentication below), but that token only needs a Register Service account — no invoker onboarding.

Endpoint

GET https://<capifRoot>/open-api-disc/v1/service-apis

<capifRoot> is your CCF host (for example capifcore inside the OpenCAPIF docker/Helm deployment).

Authentication

Every request to this endpoint must carry a bearer token:

Authorization: Bearer <access_token>

To obtain a token:

  1. Register a user account with the Register Service (or use an account you already have).
  2. Call GET /getauth on the Register Service, authenticating with HTTP Basic Auth (the username/password you registered). The response contains:
  3. access_token: a JWT to use as your bearer token.
  4. ca_root: the CA certificate to verify the CCF's TLS certificate.
  5. a set of convenience URLs, including ccf_open_discover_url (open-api-disc/v1/service-apis).
  6. Send access_token as the Authorization: Bearer header on your Open Discover requests, verifying TLS against ca_root.

Two things worth knowing about how this is enforced, so you are not surprised by the failure mode:

  • The reverse proxy in front of the CCF only checks that the Authorization header is present and syntactically looks like Bearer <something>; it does not validate the token itself. If the header is missing entirely, you get a 401 directly from the proxy (see Errors).
  • The Open Discover service itself validates the token's signature (RS256) but does not check that the token belongs to a specifically onboarded API Invoker — any valid token issued by the Register Service for any registered user is accepted for this endpoint. If the token is missing, expired, or has an invalid signature once it reaches the service, you get a different 401 response shape than the proxy-level one (see below).

Unlike several other CAPIF endpoints in this platform, this route does not require a mutual-TLS client certificate.

Query parameters

All parameters are optional; omitting all of them returns every published Service API. Array-valued parameters use OpenAPI "form" style with explode: false: pass multiple values as one comma-separated parameter, for example api-names=service_1,service_2 — not api-names[]=... or bracket/JSON array syntax.

Parameter Type Description Multiple values mean
api-names array(string) Name(s) of the target Service API(s). Any of these names
api-ids array(string) Identifier(s) of the target Service APIs. Any of these IDs
api-cats array(string) Category(ies) of the target Service API(s). Any of these categories
api-prov-names array(string) Name(s) of the provider(s) of the target Service API(s). Any of these provider names
api-versions map(array(string)) Major version(s) of the target API(s), keyed by API name (only relevant together with api-names). Currently requires the API to support all listed versions, not just one — see caveat below
comm-type string Communication type supported by the target API(s) (e.g. REQUEST_RESPONSE). n/a (single value only)
protocols array(string) Protocol(s) supported by the target API(s) (e.g. HTTP_1_1, HTTP_2). Currently requires the API to support all listed protocols — see caveat below
data-format string Data format supported by the target API(s) (e.g. JSON). n/a (single value only)
preferred-aef-loc object Preferred AEF location; ignored if there is no matching record. Send as a JSON object, e.g. preferred-aef-loc={"dcId":"dc1"}. n/a
api-supported-features map(object) Feature(s) supported by the API(s) named in api-names, keyed by API name. Only valid together with api-names. Any of the listed (API name, feature) pairs
service-kpis object Service characteristics of the target API(s) (e.g. maxReqRate, availability). n/a
res-ops array(object) Supported resource(s)/operation(s), e.g. {"resource":"...","operations":["GET"]}. n/a
supported-features string Client-side feature negotiation bitmap. Send only when negotiating a feature. n/a
vendor-specific parameters Vendor-specific query parameters, used in addition to the parameters above.

Caveat on api-versions and protocols: as of this writing, requesting more than one value for these two parameters returns only APIs that satisfy every listed value, rather than any one of them. Whether "any" or "all" is the intended semantics has not been confirmed against a project decision; treat this as current behaviour, not a guaranteed contract, until it is confirmed.

Fixed 2026-08: api-names, api-ids, api-cats, and api-prov-names previously returned no results at all (404) whenever more than one value was requested, because the values were combined as if an API had to match every one simultaneously — impossible for these single-valued attributes. This has been corrected so that a multi-value request returns any API matching at least one of the listed values.

Errors

All error responses use the CAPIF ProblemDetails shape (title, status, detail, cause, and optionally invalidParams).

Status Cause When it happens
401 Unauthorized detail: "Access token not present", cause: "Bearer token is required for this API route" No Authorization header sent at all (rejected by the reverse proxy, before reaching the service).
401 Unauthorized / 422 (default flask-jwt-extended error body, not the ProblemDetails shape) An Authorization: Bearer header is present but the token is missing, malformed, expired, or has an invalid signature once it reaches the service.
400 Bad Request detail: "Invalid query parameter format", cause: "preferred-aef-loc must be sent as an application/json query parameter" preferred-aef-loc sent using bracket notation instead of a JSON object.
400 Bad Request detail: "Invalid query parameter format", cause: <exception message> Any other query parameter value that cannot be parsed as required (e.g. malformed JSON for an object-shaped parameter).
404 Not Found detail: "No API Published accomplish filter conditions" The request is well formed, but no published Service API matches the given filters (or none are published at all).
500 Internal Server Error detail: "An exception occurred in open discover services", cause: <exception message> An unexpected server-side error.

Example requests

Retrieve every published Service API:

curl -s https://capifcore/open-api-disc/v1/service-apis \
  --cacert ca_root.crt \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Filter by one or more API names:

curl -s "https://capifcore/open-api-disc/v1/service-apis?api-names=service_1,service_2" \
  --cacert ca_root.crt \
  -H "Authorization: Bearer $ACCESS_TOKEN"

Filter by preferred AEF location:

curl -s 'https://capifcore/open-api-disc/v1/service-apis?preferred-aef-loc={"dcId":"dc1"}' \
  --cacert ca_root.crt \
  -H "Authorization: Bearer $ACCESS_TOKEN"