---
title: "Search credentials"
method: POST
path: "/v1/credentials/search"
tags: ["Credentials"]
---

# Search credentials

`POST /v1/credentials/search`

1. [Introduction](#introduction)
     * [Example Request](#example-request)
  2. [Filtering](#filtering)
     * [Logical Operators](#logical-operators)
       * [AND](#and)
       * [OR](#or)
       * [NOT](#not)
     * [Field Types & Comparison Operators](#field-types--comparison-operators)
       * [String Fields](#string-fields)
       * [UUID Fields](#uuid-fields)
       * [Enum Fields](#enum-fields)
       * [Date Fields (YYYY-MM-DD)](#date-fields-yyyy-mm-dd)
       * [DateTime Fields (ISO 8601)](#datetime-fields-iso-8601)
       * [Handling Null Values](#handling-null-values)
       * [In Operator Limitation for Null Values](#in-operator-limitation-for-null-values)
  3. [Credentials Searchable Fields](#credentials-searchable-fields)
     * [Core Fields](#core-fields)
     * [Recipient Fields](#recipient-fields)
     * [Temporal Fields](#temporal-fields)
  4. [Sorting](#sorting)
     * [Credentials Sortable Properties](#credentials-sortable-properties)
  5. [Pagination](#pagination)
  6. [Complete Example](#complete-example)
  7. [Tips and Advanced Use](#tips-and-advanced-use)
     * [Implicit AND](#implicit-and)
       * [Top-Level Logical Operators](#top-level-logical-operators)
       * [Filter Condition Objects](#filter-condition-objects)
       * [Comparison Operator Expressions](#comparison-operator-expressions)

  ## Introduction

  The Credentials Search API allows you to find and filter credentials using structured queries with logical operators, sorting, and pagination.

  A search request payload consists of:

  * **`filter`** – to define search conditions using `AND`, `OR`, and `NOT` logical operators.
  * **`sort`** – containing `property` and `order`, allowing control over result ordering.
  * [Standard pagination](https://developers.certifier.io/reference/pagination) using `cursor` and `limit`.

  ### Example Request

  ```
  POST /v1/credentials/search
  Content-Type: application/json
  ```

  ```json
  {
    "filter": {
      "AND": [
        {
          "status": {
            "equals": "issued"
          }
        },
        {
          "recipient": {
            "name": {
              "contains": "John"
            }
          }
        }
      ]
    },
    "sort": {
      "property": "createdAt",
      "order": "desc"
    },
    "cursor": "some_cursor_value",
    "limit": 25
  }
  ```

  ***

  ## Filtering

  Filter allows complex queries by combining multiple conditions using logical operators.

  ### Logical Operators

  Logical operators define how multiple conditions are combined.

  #### `AND`

  All conditions must be met.

  ```json
  {
    "filter": {
      "AND": [
        {
          "status": {
            "equals": "issued"
          }
        },
        {
          "recipient": {
            "email": {
              "endsWith": "@company.com"
            }
          }
        }
      ]
    }
  }
  ```

  #### `OR`

  At least one condition must be met.

  ```json
  {
    "filter": {
      "OR": [
        {
          "status": {
            "equals": "draft"
          }
        },
        {
          "status": {
            "equals": "expired"
          }
        }
      ]
    }
  }
  ```

  #### `NOT`

  Excludes records that match the condition.

  ```json
  {
    "filter": {
      "NOT": [
        {
          "status": {
            "equals": "expired"
          }
        }
      ]
    }
  }
  ```

  Operators can be combined:

  ```json
  {
    "filter": {
      "AND": [
        {
          "NOT": [
            {
              "recipient": {
                "email": {
                  "endsWith": "@company.com"
                }
              }
            }
          ]
        },
        {
          "recipient": {
            "name": {
              "startsWith": "John"
            }
          }
        }
      ]
    }
  }
  ```

  ### Field Types & Comparison Operators

  Comparison operators define how field values are filtered.

  #### String Fields

  ```json
  {
    "recipient": {
      "name": {
        "contains": "John"
      }
    }
  }
  ```

  * `equals`: Exact match
  * `contains`: Partial match
  * `startsWith`: Prefix match
  * `endsWith`: Suffix match
  * `in`: Matches any value in an array

  #### UUID Fields

  UUID fields (such as `publicId`) only support exact matching. Each value must be a valid UUID — malformed values are rejected.

  ```json
  {
    "publicId": {
      "equals": "124a8110-1af5-4747-9308-e9d06bd1852a"
    }
  }
  ```

  * `equals`: Exact match (must be a valid UUID)
  * `in`: Matches any value in an array (each must be a valid UUID)

  #### Enum Fields

  ```json
  {
    "status": {
      "in": [
        "draft",
        "expired"
      ]
    }
  }
  ```

  * `equals`: Exact match
  * `in`: Matches any value in an array

  #### Date Fields (`YYYY-MM-DD`)

  ```json
  {
    "issueDate": {
      "gte": "2024-01-01"
    }
  }
  ```

  * `equals`: Exact match
  * `lt`: Less than
  * `lte`: Less than or equal
  * `gt`: Greater than
  * `gte`: Greater than or equal

  #### DateTime Fields (ISO 8601)

  ```json
  {
    "createdAt": {
      "gte": "2025-02-21T14:18:33Z"
    }
  }
  ```

  * `equals`: Exact match
  * `lt`: Less than
  * `lte`: Less than or equal
  * `gt`: Greater than
  * `gte`: Greater than or equal

  #### Handling Null Values

  ```json
  {
    "expiryDate": {
      "equals": null
    }
  }
  ```

  * `{ "expiryDate": { "equals": null } }`: Matches records where the field is `null`.
  * `{ NOT: [{ "expiryDate": { "equals": null } }] }`: Excludes records where the field is `null`.

  #### `in` Operator Limitation for Null Values

  The `in` operator **does not support** `null` values. If you need to match `null` alongside other values, use an `OR` logical statement instead:

  ```json
  {
    "filter": {
      "OR": [
        {
          "recipientId": {
            "equals": null
          }
        },
        {
          "recipientId": {
            "in": [
              "01jmerb62apgachxwx6db76c7s",
              "01jmerbnaa9r183ry7a4mpe4v8"
            ]
          }
        }
      ]
    }
  }
  ```

## Headers

- `Certifier-Version` string, required — API version header. Required for all requests.

## Request body

- SearchCredentials
  - `filter` object — Filter object with AND, OR, NOT operators and field conditions. Supports filtering by id, publicId, groupId, status, recipientId, recipient.name, recipient.email, issueDate, expiryDate, createdAt, updatedAt
  - `sort` object — Sorting options
    - `property` 'id' | 'createdAt' | 'updatedAt' | 'issueDate' | 'expiryDate', required — Property to sort by. Available: id, createdAt, updatedAt, issueDate, expiryDate
    - `order` 'asc' | 'desc', required — Sort order (asc or desc, default: desc)
  - `cursor` string, nullable — Cursor for pagination
  - `limit` integer — Number of items to return (default: 20)

## Response `200`

Search results

- object
  - `data` Credential[], required
    - `id` string, required — The unique credential's identifier
    - `publicId` string, uuid, required — The external unique credential's identifier (used in the digital wallet to generate a URL, e.g. https://credsverse.com/credentials/{publicId})
    - `groupId` string, required — The unique identifier of the group (credential template).
    - `status` 'draft' | 'scheduled' | 'issued' | 'expired', required — The status of the credential
    - `recipient` Recipient, nullable, required — The recipient object (if an email was provided)
      - `id` string, required — The credential recipient's unique identifier
      - `name` string, required — The name of the credential's recipient
      - `email` string, email, required — The email of the credential's recipient
    - `issueDate` string, required — The date of your credential's issuance. Formatted as an ISO 8601 date string (YYYY-MM-DD)
    - `expiryDate` string, nullable, required — The date of your credential's expiration. Formatted as an ISO 8601 date string (YYYY-MM-DD)
    - `attributes` object, required — The key-value object of the credential's attributes. Currently this can only be the recipient.name, configured on a per-credential basis
    - `customAttributes` object, required — The key-value object of your custom attributes, where key is your attribute's tag and value is the text value you want to store
    - `createdAt` string, date-time, required — The date and time when this credential was created. Formatted as an ISO 8601 date and time string
    - `updatedAt` string, date-time, required — The date and time when this credential was updated. Formatted as an ISO 8601 date and time string
  - `pagination` object, required
    - `prev` string, nullable, required — Cursor for previous page
    - `next` string, nullable, required — Cursor for next page

## Other responses

- `400` — Bad Request - Missing version, invalid version, invalid JSON, or validation error
- `401` — Unauthorized - Invalid or missing authentication token
- `429` — Rate Limited - Too many requests
- `500` — Internal Server Error - Problem on Certifier's end

---

[API](https://skmtc.dev/certifier/apis/certifier-api.md) · [All operations](https://skmtc.dev/certifier/apis/certifier-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/certifier/certifier-api/revisions/a84fb47b7f6f/schema)
