Credential Engine Registry Search API Handbook

Last Updated on 9/7/2022

Overview

The Credential Registry Search API provides a way to programmatically search the Credential Registry and return top-level resources based on data within those resources, including their connections to other resources. This guide explains how to use the Search API.

Requirements

To use the Search API, you will need:

Use Cases and Alternative Consuming Methods to Consider

The Search API is intended to cover a wide variety of use cases involving queries to the Registry. However, there are some cases where alternative approaches will yield better results.

Getting Real-Time Data

The Search API is well-suited to retrieving real-time data from the Registry. The search index is kept up to date with the Registry itself, and is typically current within a few minutes of new records being published. This kind of usage is the primary purpose of the Search API.

While it is possible to find many resources by searching for them, the resources in the Registry are highly linked together. These links are leveraged by the Search API to build its index, but you can leverage these links directly. For example, you can follow the links in a Credential record to find all of the Competencies it requires. Following the links in the resources directly does not require use of the Search API, nor does it require an API key or even a Credential Engine account. This process is also typically instantaneous, as no query is necessary to return a record that is linked to from another record. For these reasons, it is worth considering whether your particular use case can be satisfied by simply following the links in the records themselves.

In some cases, a hybrid approach is best. For example, using a query to find a list of credentials, and then following the links in those credentials to find their associated competencies.

It's also worth keeping in mind that many properties in CTDL are inverse of each other (for example, "offers" and "offeredBy"). The data in the records in the registry is dependent on the publishers, so in some cases one side or the other of these two-way connections may not be complete or available in the records. For these cases, it is advisable to use the Search API to traverse these connections in both directions and ensure that you retrieve the full set of data.

For more information about how these records link together, including ways to manipulate the URIs to load even more information, see the CTID page.

Scraping the Registry or Downloading Records in Bulk

The Search API is not intended to enable scraping of the Registry to download large quantities of records in bulk. An example of this usage includes doing a search for all resources of a given type and paging through the results to download thousands of records.

If your use case requires this kind of data, you should instead use one of these options for Bulk Download for Offline Use.

Credential Engine monitors for use of the Search API for mass downloading of resources, and will contact you if this behavior is detected.

CTDL JSON Query Structure

The Search API uses a unique query structure built from plain JSON that leverages the actual properties and structure of CTDL and the related schemas. This structure is intended to enable highly flexible queries that allow finding resources based on properties deep within the records or even based on connections to other records. This section explains various features of this query structure.

Basics

The Search API expects a JSON object as an input, which serves as a simple wrapper to carry paging and sorting information, as well as the CTDL query itself. This section focuses specifically on the CTDL query inside of this wrapper.

Filter By Resource Type

Use the @type property to filter results to a given CTDL type or list of types.

Filter By Text Properties

The Search API supports a number of features for querying properties that have text-based values, including plain strings, URIs, language maps, and dates.

By default, all string-based fields allow for case-insensitive partial matches. For language map fields (such as ceterms:name or ceterms:description, the Search API abstracts away the intricacies of the language map itself, allowing you to query these fields as if their values were plain strings.

It is possible to force more specific kinds of matching by using a JSON object with search:value and search:matchType properties as shown:

Valid values for search:matchType include:

  • search:exactMatch - Will only match if the string is an exact match (case-insensitive) to the provided value
  • search:contains - Will only match if the string contains an exact match (case-insensitive) to the provided value
  • search:startsWith - Will only match if the string starts with the provided value
  • search:endsWith - Will only match if the string ends with the provided value

Matching CTIDs and URIs

In addition to the support for partial matches described above, the Search API also supports matches based on resource URIs and CTIDs. The Search API's index is optimized to work faster if you provide a full URI where expected, but a CTID in a URI property will also work.

Filtering by Boolean Properties

There are a handful of boolean properties in CTDL. The default value for these properties is null, so you only need to use them if you are looking for an explicitly true or false value. Otherwise, these properties will be ignored when filtering.

Filtering by Numeric Properties

The Search API supports querying for numeric properties, both directly, or as a range by searching for an array with exactly two values where the first value is the minimum boundary, and the second value is the maximum boundary (both the upper and lower bounds are inclusive):

Range queries require an array with exactly two values, and only work with properties whose values are numeric (otherwise they will be treated like any normal array of potential options - in other words, an array of three numbers will only match results that contain at least one of those numbers):

Range queries also may also be unbounded at one end or the other - just pass null to remove the associated boundary:

Filtering by Date Properties

As with numeric properties, the Search API supports querying for date properties both directly, or as a range (both upper and lower bounds are inclusive; see above for more details). Note that you will need to use the ISO 8601 date format when writing dates:

Date queries can also be unbounded at one end or the other; just pass an empty string to remove the associated boundary:

Filtering by Concepts

There are many areas of CTDL where controlled values (Concept Schemes) are used. Concepts from these schemes may be referenced either directly or via Credential Alignment Object, depending on the property in question.

For querying properties that use Credential Alignment Object as their value, see the Filtering by Credential Alignment Objects section below.

Filtering by Current Data

The Search API allows for querying all resources in the Registry, including those which are no longer considered to be in use or available. This is intentional, as it allows the lookup of older credentials which may still be valid even if they are no longer offered.

There are three primary properties (and their associated concept schemes) for describing the status of a resource:

  • For Credentials, use the ceterms:credentialStatusType property with terms from the ceterms:CredentialStatus concept scheme.
  • For Competency Frameworks, Concept Schemes, and Progression Models, use the ceasn:publicationStatusType property with the ceasn:PublicationStatus concept scheme.
  • For many other top-level resources in CTDL, use the ceterms:lifeCycleStatusType property with the ceterms:LifeCycleStatus concept scheme.

Filtering by Any Value or No Value for a Property

In some cases, you only need to know if a resource has a given property, regardless of the value of that property. For these cases, use the special token search:anyValue as the value for the property in question:

Similarly, the special token search:noValue can be used to find records which do not have any value for the property in question:

Nested Data

To filter resources based on data that is nested within them, simply use a nested JSON object:

This nesting matches the structure of the CTDL records, and may occur several times for deeply-nested data:

Note that while it's possible to explicitly indicate the @type(s) of the nested objects, it often isn't necessary, particularly when the property referencing them only ever points to instances of a single class.

For more examples, see the Examples section.

Objects and Arrays: Logical AND vs Logical OR

Often, you will want to find resources which have certain values for multiple properties. For example, you may want all Certificates with "nurse" in their name. Or, you may want results that match any value from a list of potential values, such as credentials with "developer" or "programmer" in their keywords. The Search API allows for such cases by way of the structure of the JSON itself, and a few special tokens to allow further control over how the data is queried.

By default, all properties in a JSON object are treated as being logically AND-ed together:

By contrast, all tokens in a JSON array are treated as being logically OR-ed together:

There are cases where you may want to override these behaviors. This can be done via the special property search:operator and the special token values, search:orTerms and search:andTerms:

Note that for arrays, the search:operator property and its search:andTerms value exist alongside the array rather than within it, all of which is wrapped in an otherwise empty JSON object:

For more examples, see the Examples section.

Controlling Filter Evaluation via Term Groups

When overriding logical AND-ing and OR-ing, it is often necessary to group sets of terms together. For example, you may want all resources where the type is a ceterms:Certificate regardless, but also where either the name or the description may contain "nurse". This kind of query can be done with the special property search:termGroup, which can be thought of as adding parenthesis around a set of terms within a query to force a specific order of operations and logical AND or OR within that group.

Note that despite using a nested JSON object, search:termGroup does not trigger traversal across or into an object in the data; it operates on the object itself.

For more examples, see the Examples section.

Graph Traversal

The most powerful feature of linked data is, of course, the linking between resources. The Search API is designed to allow you to perform such traversal by structuring your query as though all of the data is nested, even across multiple resources:

In some cases, it is necessary to traverse the graph connections in reverse. This can be done just like normal graph traversal, except that you will prefix the reverse properties with ^:

These forward and reverse connections can be mixed as needed in a deeply nested query. For more examples, see the Examples section.

Filtering by Credential Alignment Objects

Credential Alignment Object provides a way to link to another resource, such as a competency or concept, and/or to provide a name and description of the intended data, even when no such resource exists. While this is convenient for publishing data, it must be taken into account when querying the data. Aside from needing to be aware of where and when the schema uses a Credential Alignment Object, the actual structure of the query works as it would with any other nesting and traversal:

For more examples of queries that flow through Credential Alignment Object, see the examples section below.

Special Features

The Search API also enables some special tokens for filters based on record metadata. The sections below describe these features.

Filtering by Record Owner and Record Publisher

In some cases, it is necessary to filter records to just those that are owned or published by a specific organization. Note that ownership and publishing, in this case, refers to ownership and/or publishing of the record itself, not necessarily of the resource that the record describes.

To filter records to a specific owner or publisher, use the CTID of the organization along with the special search:recordOwnedBy or search:recordPublishedBy properties:

Filtering by Record Created Date and Record Updated Date

It is also possible to filter records based on when the record was published to the Registry and/or when that record was most recently updated. This is not to be confused with sorting by these dates. As with other date properties, these can be queried based on a date range where both the upper and lower bounds of the range are inclusive.

Note: When a record is initially created, both its search:recordCreated and its search:recordUpdated dates are set to the same value. Subsequent updates to the record will only update the value of search:recordUpdated.

Filtering by Primary and Secondary Record Source

In most cases, a record in the Registry comes from a primary source (that is, the intellectual property owner of that resource). These records may be published in one of three ways:

  • The record was directly published by the primary source itself.
  • The record was published by a third party with the explicit authorization of the primary source itself, but otherwise originated from that primary source (this is commonly called "third-party publishing").
  • The record was published by a third party with overriding authority, such as a state agency, to publish for that source without needing its permission (this is commonly called "trusted third-party publishing").

However, there are special rare cases where an organization needs to publish data for which it is not a primary source, but where the organization's authority does not rise to the level of trusted third-party publisher. For these cases, Credential Engine may authorize such an organization to perform "secondary source" publishing. A record published by a secondary source is just like any other record, except that its metadata indicates that it is a secondary source record.

By default, the Search API will include primary and secondary source records in its results. You can filter primary or secondary records in or out using the search:resourcePublishType property, with a value of either primary or secondary

Filtering by Subclasses

The CTDL schema has a number of class hierarchies. The most obvious example of these are the various subclasses of Credential, which form a tree of subclasses. The Search API allows you to explicitly select one or more of these subclasses of credential, but there are cases where you are looking for any kind of credential, regardless of its specific subclass. To avoid needing to keep track of (and write queries with) every subclass of Credential, you can use the following value for @type:

This also works for any other classes that have subclasses. As with the Certificate example above, results will include the class you specify, as well as subclasses of that class.

The CTDL Types List page provides a useful reference for the various class/subclass hierarchies in CTDL.

Additional Considerations

The CTDL family of schemas provides a variety of ways to describe information. It also provides a variety of places for that information to be stored. When searching for information in the Registry via the Search API, you will need to consider all of the places in CTDL where that information may have been expressed, and write your queries to check all of them. Some common examples are below.

Owns vs Offers vs Owned By vs Offered By vs Creator vs Publisher vs Record Owned By vs Record Published By

There are a number of properties in the CTDL family of schemas for connecting resources to the organizations that provide them. However, the notion of "providing" a resource encompasses several more granular notions, each of which have their own specific properties. Additionally, there is a distinction between the records in the Registry and the resources those records describe.

  • ceterms:owns - Points from an organization to a resource, and indicates that the organization is the intellectual property owner of that resource
  • ceterms:offers - Points from an organization to a resource, and indicates that the organization offers that resource, typically to end users
  • ceterms:ownedBy - Points from a resource to an organization, and indicates that the organization is the intellectual property owner of that resource
  • ceterms:offeredBy - Points from a resource to an organization, and indicates that the organization offers that resource, typically to end users
  • ceasn:creator - Points from a resource to an organization, and indicates that the organization created that resource
  • ceasn:publisher - Points from a resource to an organization, and indicates that the organization makes that resource available, typically to end users
  • search:recordOwnedBy - Special Search API property (see above) indicating the organization that owns the record in the registry (regardless of the owner of the resource)
  • search:recordPublishedBy - Special Search API property (see above) indicating the organization that published the record in the registry (regardless of who makes that resource available to others)

Compounding this, data may be present for some of these properties, but not others (data is always present for the two special search API properties). This is due to differences in which properties certain organizations choose to use, when/how often they update their data, and rules preventing publishers from modifying data they do not own. This leads to subtle inconsistencies in the connections between records that need to be accounted for when using the Search API.

Some common examples include:

  • A credential may indicate that it is "owned by" an organization, but not have any "offered by" data even when it is also offered by that organization
  • A credential may indicate that it is "offered by" an organization, but that organization's record may not indicate that it "offers" that credential
  • A competency framework may only indicate that its "creator" is a particular organization, even when that organization is also its publisher

Typically, the safest approach is to rely on the connections that exist on the resource and point to the organization. This kind of data is usually part of the minimum requirements for publishing the resource, so it is more likely to be present.

Quality Assurance

Quality Assurance is expressed in CTDL via a series of properties, each with an inverse:

  • ceterms:accredits points from the Organization doing the accrediting to the resource being accredited. Its inverse is ceterms:accreditedBy which points from the resource being accredited to the Organization that does the accrediting.
  • ceterms:approves points from the Organization doing the approving to the resource being approved. Its inverse is ceterms:approvedBy which points from the resource being approved to the Organization that does the approving.
  • ceterms:recognizes points from the Organization doing the recognizing to the resource being recognized. Its inverse is ceterms:recognizedBy which points from the resource being recognized to the Organization that does the recognizing.
  • ceterms:regulates points from the Organization doing the regulating to the resource being regulated. Its inverse is ceterms:regulatedBy which points from the resource being regulated to the Organization that does the regulating.

The nature of the data published to the Registry means that the above connections will not always be present in both directions. For example, a government agency may publish its own Organization record to the Registry, but not provide a list of credentials that it accredits. Publishers of the data for those credentials, however, may provide such data. In this case, the ceterms:accreditedBy connections will exist, but the ceterms:accredits connections will not. Therefore, the lack of connections flowing both ways does not necessarily imply that a false claim of quality assurance is being made, but if this data is important to your use case, you should reach out to the publishers in question to verify the information.

Additionally, some Organizations perform quality assurance on other Organizations, or on the programs those Organizations offer, rather than on the Credentials themselves. This must also be taken into account when building your queries.

Addresses

A common use case is to look for credentials that are available in a particular area, such as a state. There are several ways that the physical location where a resource is offered can be communicated in CTDL, each of which will need to be accounted for when looking for resources based on location. Which ways are in use for a given record depends on the which properties the publisher of the data chose to use, but will fall into one or more of these categories:

  • On the resource itself, generally via ceterms:availableAt or ceterms:availablilityListing
  • Described in detail for the resource itself via ceterms:hasOffering
  • Indirectly via a related resource, such as the required assessments or learning opportunities for a credential (also communicated using ceterms:availableAt or ceterms:availablilityListing)
  • Implicitly via the address(es) of the organization(s) that offer(s) the resource, via ceterms:address
  • Implicitly via the jurisdiction(s) of the organization(s) that offer(s) the resource, via ceterms:jurisdiction

When querying for locations, you will need to leverage the structure of the ceterms:Place class, which contains various familiar properties for describing an address at varying levels of granularity.

Address matching can be somewhat awkward when there is more than one way to write an address. For example, in the US, the ceterms:addressRegion may be published with either the full name of a state, or its two-character postal shorthand. Both kinds of address need to be accounted for in order to avoid missing valid resources, while also avoiding false positives where the two-character string is a substring of a full state's name (for example, Indiana's abbreviation, "IN", can be found in "North Carolina". To handle this, you will need to look both for the full name of the state and its exact abbreviation via search:matchType and search:exactMatch, as shown in the examples below.

You should also be aware that many resources may (also) be offered online. This would be indicated via use of ceterms:availableOnlineAt.

Combining the above and making use of a Term Group, we can look for Certificates based on address even when we don't know exactly where the address data is published:

Credential Data Describing Related Resources

Some properties of credentials are intended to provide shortcuts for publishers of the data, to avoid needing to publish records for related data, such as assessments or learning opportunities. These properties will also need to be accounted for when designing your queries. For example:

  • ceterms:assessmentDeliveryType exists on credentials, but actually describes the ceterms:deliveryType of a related assessment (often where there is no actual assessment record).
  • ceterms:learningDeliveryType exists on credentials, but actually describes the ceterms:deliveryType of a related learning opportunity (often where there is no actual learning opportunity record).
  • Several properties exist on credentials, but typically actually apply to the program, course, or assessment that leads to the credential, rather than the credential itself. Some examples include:
    • ceterms:availableAt
    • ceterms:availableOnlineAt
    • ceterms:availabilityListing
    • ceterms:estimatedCost
    • ceterms:estimatedDuration

Returning Data

The results returned by the Search API always consist of the entire Registry record for each result, for the current "page" of results (in addition to a count of total results). There is no need to specify particular properties to return.

The following sections describe different aspects of how data is returned from the Search API.

Note that the following sections show the complete HTTP POST body object that would be sent to the Search API, whereas the examples above focus on the CTDL portion of the query.

Top-Level Resources

The Search API will only return results consisting of "top level" classes. Top level classes are those which have a CTID property. The following is a list of classes with CTIDs:

asn:ProgressionLevelasn:ProgressionModelceasn:Competencyceasn:CompetencyFrameworkceasn:Rubricceasn:RubricCriterionceterms:AcademicCertificateceterms:AccreditActionceterms:AdvancedStandingActionceterms:ApprenticeshipCertificateceterms:ApproveActionceterms:AssessmentComponentceterms:AssessmentProfileceterms:AssociateDegreeceterms:AssociateOfAppliedArtsDegreeceterms:AssociateOfAppliedScienceDegreeceterms:AssociateOfArtsDegreeceterms:AssociateOfScienceDegreeceterms:BachelorDegreeceterms:BachelorOfArtsDegreeceterms:BachelorOfScienceDegreeceterms:Badgeceterms:BasicComponentceterms:BasicTechnicalCertificateceterms:Certificateceterms:CertificateOfCompletionceterms:CertificateOfParticipationceterms:Certificationceterms:CocurricularComponentceterms:Collectionceterms:CollectionComponentceterms:CompetencyComponentceterms:ConditionManifestceterms:CostManifestceterms:Courseceterms:CourseComponentceterms:Credentialceterms:CredentialComponentceterms:CredentialingActionceterms:CredentialOrganizationceterms:Degreeceterms:DigitalBadgeceterms:Diplomaceterms:DoctoralDegreeceterms:ExtracurricularComponentceterms:GeneralEducationDevelopmentceterms:GeneralEducationLevel1Certificateceterms:GeneralEducationLevel2Certificateceterms:HigherEducationLevel1Certificateceterms:HigherEducationLevel2Certificateceterms:Jobceterms:JobComponentceterms:JourneymanCertificateceterms:LearningOpportunityProfileceterms:LearningProgramceterms:Licenseceterms:MasterCertificateceterms:MasterDegreeceterms:MasterOfArtsDegreeceterms:MasterOfScienceDegreeceterms:MicroCredentialceterms:MultiComponentceterms:Occupationceterms:OfferActionceterms:OpenBadgeceterms:Organizationceterms:Pathwayceterms:PathwaySetceterms:PostBaccalaureateCertificateceterms:PostMasterCertificateceterms:PreApprenticeshipCertificateceterms:ProfessionalCertificateceterms:ProfessionalDoctorateceterms:ProficiencyCertificateceterms:QACredentialOrganizationceterms:QualityAssuranceCredentialceterms:RecognizeActionceterms:RegistrationActionceterms:RegulateActionceterms:RenewActionceterms:ResearchDoctorateceterms:RevokeActionceterms:RightsActionceterms:ScheduledOfferingceterms:SecondaryEducationCertificateceterms:SecondarySchoolDiplomaceterms:SpecialistDegreeceterms:SupportServiceceterms:Taskceterms:TechnicalLevel1Certificateceterms:TechnicalLevel2Certificateceterms:TechnicalLevel3Certificateceterms:TransferIntermediaryceterms:TransferValueProfileceterms:VerificationServiceProfileceterms:WorkBasedLearningCertificateceterms:WorkExperienceComponentceterms:WorkforceDemandActionceterms:WorkRoleskos:Conceptskos:ConceptSchemeqdata:DataSetProfile

Paging: Skip and Take

Pagination is handled via the Skip and Take properties of the root of the query:

  • The Skip property indicates how many results (not how many pages) to skip, and uses a 0-based index.
  • The Take property indicates how many of the remaining results (after skipping) to include in the response. It has a maximum limit of 100 resources per page.

Sort Order

You can control the sort order of results via the Sort property of the root of the query:

The Sort property accepts one of the following values:

  1. search:relevance - This will return results based on how closely their text-based properties match any text-based properties in your query. This is the default order if your query contains any text matching properties.
  2. search:recordUpdated - This will return results based on how recently the record was updated, with the most recently updated records coming first. This is the default order if your query does not contain any text matching properties.
  3. search:recordCreated - This will return results based on how recently the record was created, with the most recently created records coming first.
  4. You can also sort based on any alphanumeric property in the root level of the search results. For example, use ceterms:name to order results alphabetically (A-Z) by name.

Note: Do not confuse the usage of search:recordCreated and search:recordUpdated here as sort orders in the root of the query with the usage of those properties as filters in the body of the query as shown here.

To reverse the sort order, prefix the value with ^. For example, to sort records by ceterms:name in reverse (Z-A), use ^ceterms:name.

Record Metadata

Additional metadata about the search results are also available as part of the response to a query. This metadata is encapsulated in an array of JSON objects separate from the results themselves, where each object in the array goes with one of the results. Such metadata includes:

  • ResourceURI - The URI of the search result that this metadata object describes
  • RecordCreated - The date and time that this Record was created in the Registry
  • RecordUpdated - The date and time that this Record was most recently updated in the Registry
  • RecordOwnedBy - The CTID of the organization that owns this Registry record (but does not necessarily own the resource described by the record)
  • RecordPublishedBy - The CTID of the organization that published this Registry record (but does not necessarily publish the resource described by the record)
  • RecordPublishType - Indicates whether this Record is considered a primary or secondary source record.

You can include the metadata in the response by using "IncludeResultsMetadata": true in the root of your query:

This will be included in the ResultsMetadata property of the response object:

Graph Data

Some resources contain additional objects in their JSON-LD @graph. These objects range from stub references to things which do not have full registry records (RDF Blank Nodes) to resources that exist as top level resources, but which are also closely tied to some other resource, such as:

  • The Competencies for a Competency Framework
  • The Concepts for a Concept Scheme
  • The Pathway Components for a Pathway

You can include the data from the @graphs for the results by using "IncludeGraphData": true in the root of your query:

All of the additional data from the results' @graphs (not including the results themselves) will be returned in the RelatedItems array of the response:

Description Sets and Other Related Data

A Description Set is a collection of resources directly relevant (and directly or indirectly connected to) some specific resource, typically beyond that resource's @graph. A Description Set is useful for obtaining a broad depth of data about and logically adjacent to a resource. For example, the Description Set for a credential might include:

  • The credential itself
  • The organization(s) that own or offer that credential
  • Any required assessments or learning opportunities for the credential
  • Any competencies related to the credential, either directly (e.g. the credential requires the competencies) and/or indirectly (e.g. the credential requires an assessment which assesses those competencies)
  • Other similarly relevant information

The Search API also supports returning the Description Sets for results, in two parts: The Description Set itself, and (optionally) the related resources connected via the linkages described by that Description Set. The Description Set itself is an array of objects that provide the URIs of the related resources for each result, along with a special path string that indicates the chain of properties and classes that connects that result to that list of related resources, including the directionality of those connections. A Description Set looks like this:

The example above features several key aspects of Description Sets. Namely:

  • ResourceURI - The URI of the search result being described by this Description Set. This is used because Description Sets are returned in a different part of the response from the search results themselves.
  • RelatedItems - The array of objects describing the paths to or from the search result out to some other resource or set of resources, each of which includes:
    • Path - Describes the path taken, through a series of properties and classes, between the search result and the items referenced in the URIs array. The search result is always assumed to be the leftmost object, and the rightmost object is the type of resource being referenced. Path strings may contain a mix of outbound and inbound connections, represented by > and <, respectively. For example:
      • > ceterms:offeredBy > ceterms:Agent means "The search result has a ceterms:offeredBy property that references one or more instances of ceterms:Agent (the superclass for various types of organization), which are linked to in the URIs array".
      • < ceterms:offers < ceterms:Agent means "The search result is referenced by one or more instances of a ceterms:offers property, each of which belongs a ceterms:Agent (the superclass for various types of organization), which are linked to in the URIs array".
    • TotalURIs - A count of total URIs that belong with the provided path. When the number of URIs and/or related resources returned is limited (see below), this provides a way to know how many URIs would be in the URIs array if no limit were applied.
    • URIs - The list of URIs found on the rightmost end of the path. The number of URIs in the array is subject to the limit described below.

The DescriptionSetType property of the outermost layer of the query itself controls what kind of data is returned. It has the following options:

  1. "DescriptionSetType": "Resource" returns just the results themselves. This is the default option, so you do not need to include this property if you only want the resources.
  2. "DescriptionSetType": "Resource_RelatedURIs" returns the results, plus the Description Sets for those results.
  3. "DescriptionSetType": "Resource_RelatedURIs_RelatedData" returns all of the above, plus the related resources (in the RelatedItems array of the response).

Note: Description Sets, when combined with their related resources, may contain a lot of data, and returning them will often take longer than returning just the results. Only request Description Sets if your use case requires them. This is doubly true for returning related data.

You can limit the number of URIs returned for each connection in the Description Set using the DescriptionSetRelatedURIsLimit property in the root of your query. This will also limit the related resources returned to those whose URIs were included in the response.

Since the related resources for all results are combined in a single RelatedItems array in the response, there will only be no duplicate instances of a resource in that array. However, since each "page" of results is independent of each other "page", it is possible to return the same related items multiple times if multiple pages of your results have Description Sets which reference the same related resource. In other words, if 3 Credentials on one page of your results reference the same Organization, that Organization will only appear once in the RelatedItems array. However, if that same Organization is referenced by one or more Credentials on 3 pages of your results, that Organization will be returned once for each page. So again, it is important to only return the related resources if your use case truly needs them.

Combining Graphs and Description Sets

It is possible to include @graph data in addition to Description Set data (see above). Note that the IncludeGraphData property ignores the DescriptionSetRelatedURIsLimit property, making it possible to return an entire @graph plus a limited Description Set for each result in a single query.

However, it is strongly advised that you only do so if/when truly necessary, in order to conserve resources and ensure the best speed/performance for your users. It is preferable, for example, to return only the resources for a search, and then use a separate page (after the user has clicked on a search result) to query for the @graph and/or Description Set for a single resource.

Calling the Search API

The Credential Registry supports the Search API on both its Sandbox and Production systems, with the following endpoints:

  • Sandbox: https://sandbox.credentialengine.org/assistant/search/ctdl
  • Production: https://apps.credentialengine.org/assistant/search/ctdl

To call the Search API, make an HTTP POST request to one of the above endpoints, including an Authorization header with a value of Bearer followed by a space and then your API key, for example:

Authorization Bearer abcdef12345

The body of the POST request will be the query object, for example:

For more examples, see the Query Helper section below.

Query Helper

The Query Helper is a tool meant to help developers build, test, and experiment with their queries. It provides:

  • A list of pre-made query examples
  • A simple interface for building basic queries
  • A simple query editor for creating fully customizable queries
  • An interface for configuring the root layer of the query
  • A display of exactly what the root layer of the query looks like (this is what your system will need to generate and send to the Search API in the body of your HTTP POST request)
  • Live, real-time results in both a simplified name/description display and raw JSON data formats

Additional Examples

The following sections provide additional query examples.

Simple Query Examples

Filtering by Nested Data Examples

Graph Traversal Examples

Overriding AND vs OR Examples

Term Group Examples

Credential Alignment Object Examples

Finding Credentials Connected via Pathway

Suppose you have the data for a Certificate, and want to find any Credentials that any Pathways identify as directly requiring that Certificate. In other words, you want to find 1-n other Credentials that directly require your current Credential according to 1-n Pathways:

Doing so will require following a combination of forward and reverse connections. Let's break each part of the query down into steps, and then combine them:

At this point, you have 1-n Pathway Components (just one in this example) that reference 1-n credentials via their ceterms:proxyFor property. No further querying is necessary, since you can just follow that link directly in the data.

However, if we wanted to combine all of our searching into one query, we would need to factor this extra hop in as well. Note that the combined query does not include the initial @type filter, since no unwanted kinds of entities would be a part of the complete chain of connections (in other words, only Pathway Components use all of the properties in play, so we don't need to worry about things like Collection Members).

It's also important to keep in mind that the root level of your query represents the results you want to return, which means the starting point for your query is actually the goal in the diagram above, and you need to work your way back to the starting point for your data, which is the known CTID for the Certificate.

References

BCP 47:
Best Current Practice 47 - Language Tags
https://tools.ietf.org/html/bcp47
bNode:
In RDF, a blank node (also called bnode) is a node in an RDF graph representing a resource for which a URI or literal is not given.
https://en.wikipedia.org/wiki/Blank_node
ISO 8601:
Data elements and interchange formats - Information interchange - Representation of dates and times:
https://en.wikipedia.org/wiki/ISO_8601
JSON-LD:
JSON Linked Data Specification
https://json-ld.org/
RDF:
Resource Description Framework (RDF)
https://www.w3.org/RDF/
RDF PRIMER:
Latest "RDF Primer" versions
https://www.w3.org/TR/rdf-primer/
SKOS:
Simple Knowledge Organization System (SKOS)
https://www.w3.org/2004/02/skos/
SKOS PRIMER:
SKOS (Simple Knowledge Organization System) Primer
https://www.w3.org/TR/2009/NOTE-skos-primer-20090818/
SKOS REF:
SKOS (Simple Knowledge Organization System) Reference
https://www.w3.org/TR/2009/REC-skos-reference-20090818/
URL:
Uniform Resource Locator
https://en.wikipedia.org/wiki/URL
W3C LD Glossary:
World Wide Web Consortium Linked Data Glossary
https://www.w3.org/TR/ld-glossary/