{
  "openapi": "3.1.0",
  "info": {
    "title": "Verbena CE requirements API",
    "version": "v1",
    "summary": "Continuing education requirements for behavioral health licenses in the 50 US states and DC.",
    "description": "Read-only JSON over HTTPS. One record per license per jurisdiction: hours per renewal cycle, cycle length, required topics, limits on self-study and live hours, the board notes, and links to the sources. Every version is kept, so you can ask what applies now, what applied on a date, and what changed since a date.\n\nCompiled from public licensing-board sources. Informational only, not legal advice: verify current requirements with the relevant board.",
    "contact": {
      "name": "Verbena",
      "email": "hello@verbena.health",
      "url": "https://verbena.health/contact/"
    }
  },
  "servers": [
    {
      "url": "https://api.verbena.health/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "Requirements",
      "description": "The rules themselves, now or on a date, and how they changed."
    },
    {
      "name": "Reference lists",
      "description": "What exists to build on: jurisdictions, licenses, coverage, groups, topics and a summary."
    }
  ],
  "paths": {
    "/requirements": {
      "get": {
        "tags": [
          "Requirements"
        ],
        "operationId": "listRequirements",
        "summary": "List requirements",
        "description": "Current requirements by default, one record per license, in a stable order. Pass `as_of` for the versions in force on a date instead. Filters combine. A filter that matches nothing returns an empty `data` array. A `license_group` value that is not one of the five is ignored.",
        "parameters": [
          {
            "$ref": "#/components/parameters/state"
          },
          {
            "$ref": "#/components/parameters/region"
          },
          {
            "$ref": "#/components/parameters/license_group"
          },
          {
            "$ref": "#/components/parameters/license"
          },
          {
            "$ref": "#/components/parameters/confidence"
          },
          {
            "$ref": "#/components/parameters/cpd"
          },
          {
            "$ref": "#/components/parameters/fully_async_ok"
          },
          {
            "$ref": "#/components/parameters/as_of"
          },
          {
            "$ref": "#/components/parameters/limit"
          },
          {
            "$ref": "#/components/parameters/cursor"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of requirements. Follow `next_cursor` until it is null.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "next_cursor"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Requirement"
                      }
                    },
                    "next_cursor": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pass back as `cursor` for the next page; null on the last page."
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "jurisdiction": {
                        "code": "CA",
                        "name": "California",
                        "region": "US",
                        "board": "Board of Behavioral Sciences"
                      },
                      "license_group": "Social Work",
                      "license": "LCSW (Licensed Clinical Social Worker)",
                      "cpd": false,
                      "total_hours": 36,
                      "cycle_years": 2,
                      "live_interactive_required_hours": 0,
                      "fully_async_ok": true,
                      "home_study_cap": "The board's statement on self-study limits, as plain text.",
                      "required_topics": [
                        {
                          "topic": "Law and Ethics",
                          "hours": 6,
                          "note": "Every renewal."
                        }
                      ],
                      "board_nuances": "The board's own notes: exemptions, deadlines, anything that is not a number.",
                      "source_urls": [
                        "https://www.bbs.ca.gov/"
                      ],
                      "confidence": "medium",
                      "verified_at": null,
                      "effective_from": "2026-08-12T14:03:11.000Z",
                      "effective_to": null,
                      "is_current": true,
                      "ingested_at": "2026-08-12T14:03:11.000Z"
                    }
                  ],
                  "next_cursor": "Q0F8U29jaWFsIFdvcmt8TENTVw"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "description": "A malformed date or query value.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "bad_as_of": {
                    "value": {
                      "error": "bad_as_of",
                      "detail": "ISO date expected"
                    }
                  },
                  "bad_query": {
                    "value": {
                      "error": "bad_query",
                      "detail": "query parameters cannot contain a NUL character"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/requirements?state=CA,NY&license_group=Social%20Work\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/requirements/{state}/{license_group}": {
      "get": {
        "tags": [
          "Requirements"
        ],
        "operationId": "getRequirements",
        "summary": "Get the requirements for a jurisdiction and license group",
        "description": "The records for one jurisdiction and license group, as an array, because a jurisdiction can hold more than one license in a group. Pass `as_of` for the versions in force on a date.",
        "parameters": [
          {
            "$ref": "#/components/parameters/statePath"
          },
          {
            "$ref": "#/components/parameters/licenseGroupPath"
          },
          {
            "$ref": "#/components/parameters/as_of"
          }
        ],
        "responses": {
          "200": {
            "description": "One record per license in the group.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Requirement"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "jurisdiction": {
                        "code": "CA",
                        "name": "California",
                        "region": "US",
                        "board": "Board of Behavioral Sciences"
                      },
                      "license_group": "Social Work",
                      "license": "LCSW (Licensed Clinical Social Worker)",
                      "cpd": false,
                      "total_hours": 36,
                      "cycle_years": 2,
                      "live_interactive_required_hours": 0,
                      "fully_async_ok": true,
                      "home_study_cap": "The board's statement on self-study limits, as plain text.",
                      "required_topics": [
                        {
                          "topic": "Law and Ethics",
                          "hours": 6,
                          "note": "Every renewal."
                        }
                      ],
                      "board_nuances": "The board's own notes: exemptions, deadlines, anything that is not a number.",
                      "source_urls": [
                        "https://www.bbs.ca.gov/"
                      ],
                      "confidence": "medium",
                      "verified_at": null,
                      "effective_from": "2026-08-12T14:03:11.000Z",
                      "effective_to": null,
                      "is_current": true,
                      "ingested_at": "2026-08-12T14:03:11.000Z"
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "description": "A malformed `as_of` date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "bad_as_of": {
                    "value": {
                      "error": "bad_as_of",
                      "detail": "ISO date expected"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          },
          "404": {
            "description": "The jurisdiction is not one Verbena serves, the group is not one of the five, or nothing is on record for the pair (at the `as_of` date, if given).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_jurisdiction": {
                    "value": {
                      "error": "unknown_jurisdiction",
                      "jurisdiction": "ON"
                    }
                  },
                  "unknown_license_group": {
                    "value": {
                      "error": "unknown_license_group",
                      "detail": "one of: Social Work, Counseling, Psychology, MFT, BCBA"
                    }
                  },
                  "not_covered": {
                    "value": {
                      "error": "not_covered",
                      "detail": "jurisdiction exists but this license group is not in the dataset"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/requirements/CA/Social%20Work\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/requirements/{state}/{license_group}/history": {
      "get": {
        "tags": [
          "Requirements"
        ],
        "operationId": "getRequirementHistory",
        "summary": "Get every version for a jurisdiction and license group",
        "description": "Every version on record, current and closed, newest first within each license. `effective_from` and `effective_to` give each version its window.",
        "parameters": [
          {
            "$ref": "#/components/parameters/statePath"
          },
          {
            "$ref": "#/components/parameters/licenseGroupPath"
          }
        ],
        "responses": {
          "200": {
            "description": "All versions, possibly an empty array.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Requirement"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "jurisdiction": {
                        "code": "CA",
                        "name": "California",
                        "region": "US",
                        "board": "Board of Behavioral Sciences"
                      },
                      "license_group": "Social Work",
                      "license": "LCSW (Licensed Clinical Social Worker)",
                      "cpd": false,
                      "total_hours": 36,
                      "cycle_years": 2,
                      "live_interactive_required_hours": 0,
                      "fully_async_ok": true,
                      "home_study_cap": "The board's statement on self-study limits, as plain text.",
                      "required_topics": [
                        {
                          "topic": "Law and Ethics",
                          "hours": 6,
                          "note": "Every renewal."
                        }
                      ],
                      "board_nuances": "The board's own notes: exemptions, deadlines, anything that is not a number.",
                      "source_urls": [
                        "https://www.bbs.ca.gov/"
                      ],
                      "confidence": "medium",
                      "verified_at": null,
                      "effective_from": "2026-08-12T14:03:11.000Z",
                      "effective_to": null,
                      "is_current": true,
                      "ingested_at": "2026-08-12T14:03:11.000Z"
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          },
          "404": {
            "description": "The jurisdiction is not one Verbena serves, or the group is not one of the five.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_jurisdiction": {
                    "value": {
                      "error": "unknown_jurisdiction",
                      "jurisdiction": "ON"
                    }
                  },
                  "unknown_license_group": {
                    "value": {
                      "error": "unknown_license_group",
                      "detail": "one of: Social Work, Counseling, Psychology, MFT, BCBA"
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/requirements/CA/Social%20Work/history\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/changes": {
      "get": {
        "tags": [
          "Requirements"
        ],
        "operationId": "listChanges",
        "summary": "List changes since a date",
        "description": "One row per version that took effect, or was closed, on or after `since`, newest first. `added` has no predecessor, `amended` carries a per-field `diff`, and `retired` is a version closed with no successor. Each row carries the full `current` record, so no second call is needed.\n\nBy default only material rows come back: a rule field or the board notes moved, or a requirement was added or retired. `include=all` also returns changes to our own metadata: confidence, the verification date and the source list. Overlapping windows are safe; identify a row by its jurisdiction, license group, license and `event_at`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/since"
          },
          {
            "$ref": "#/components/parameters/state"
          },
          {
            "$ref": "#/components/parameters/region"
          },
          {
            "$ref": "#/components/parameters/license_group"
          },
          {
            "$ref": "#/components/parameters/include"
          }
        ],
        "responses": {
          "200": {
            "description": "Change rows, with the window and mode that answered.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "since",
                    "include"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Change"
                      }
                    },
                    "since": {
                      "type": "string",
                      "format": "date-time"
                    },
                    "include": {
                      "type": "string",
                      "enum": [
                        "material",
                        "all"
                      ]
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "jurisdiction": "CA",
                      "jurisdiction_name": "California",
                      "region": "US",
                      "license_group": "Social Work",
                      "license": "LCSW (Licensed Clinical Social Worker)",
                      "change_type": "amended",
                      "material": true,
                      "event_at": "2026-09-03T13:20:00.000Z",
                      "diff": {
                        "total_hours": {
                          "from": 36,
                          "to": 40
                        },
                        "live_hours": {
                          "from": 0,
                          "to": 6
                        }
                      },
                      "current": {
                        "jurisdiction": {
                          "code": "CA",
                          "name": "California",
                          "region": "US",
                          "board": "Board of Behavioral Sciences"
                        },
                        "license_group": "Social Work",
                        "license": "LCSW (Licensed Clinical Social Worker)",
                        "cpd": false,
                        "total_hours": 40,
                        "cycle_years": 2,
                        "live_interactive_required_hours": 6,
                        "fully_async_ok": false,
                        "home_study_cap": "The board's statement on self-study limits, as plain text.",
                        "required_topics": [
                          {
                            "topic": "Law and Ethics",
                            "hours": 6,
                            "note": "Every renewal."
                          }
                        ],
                        "board_nuances": "The board's own notes: exemptions, deadlines, anything that is not a number.",
                        "source_urls": [
                          "https://www.bbs.ca.gov/"
                        ],
                        "confidence": "medium",
                        "verified_at": null,
                        "effective_from": "2026-09-03T13:20:00.000Z",
                        "effective_to": null,
                        "is_current": true,
                        "ingested_at": "2026-08-12T14:03:11.000Z"
                      }
                    }
                  ],
                  "since": "2026-09-01T00:00:00.000Z",
                  "include": "material"
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "description": "`since` is missing or not a date.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "bad_since": {
                    "value": {
                      "error": "bad_since",
                      "detail": "since=<ISO date> is required"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/changes?since=2026-09-01&state=CA\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/jurisdictions": {
      "get": {
        "tags": [
          "Reference lists"
        ],
        "operationId": "listJurisdictions",
        "summary": "List jurisdictions",
        "description": "Every jurisdiction Verbena serves, the 50 states and DC, with the license groups each currently has data for.",
        "parameters": [
          {
            "$ref": "#/components/parameters/region"
          }
        ],
        "responses": {
          "200": {
            "description": "Jurisdictions in name order.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/JurisdictionWithGroups"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "code": "AL",
                      "name": "Alabama",
                      "region": "US",
                      "board": "Alabama licensing board",
                      "license_groups": [
                        "BCBA",
                        "Counseling",
                        "MFT",
                        "Psychology",
                        "Social Work"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/jurisdictions\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/licenses": {
      "get": {
        "tags": [
          "Reference lists"
        ],
        "operationId": "listLicenses",
        "summary": "List licenses",
        "description": "One row per license with a current requirement, with its jurisdiction and license group. Use it to fill a picker, or to find every state that has a given license with `q`. Unpaginated, because the list is bounded by the dataset.",
        "parameters": [
          {
            "$ref": "#/components/parameters/stateStrict"
          },
          {
            "$ref": "#/components/parameters/regionStrict"
          },
          {
            "$ref": "#/components/parameters/licenseGroupStrict"
          },
          {
            "$ref": "#/components/parameters/license"
          },
          {
            "$ref": "#/components/parameters/q"
          }
        ],
        "responses": {
          "200": {
            "description": "Licenses in jurisdiction, group and license order.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/License"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "jurisdiction": {
                        "code": "CA",
                        "name": "California",
                        "region": "US",
                        "board": "Board of Behavioral Sciences"
                      },
                      "license_group": "Social Work",
                      "license": "LCSW (Licensed Clinical Social Worker)",
                      "last_changed_at": "2026-08-12T14:03:11.000Z"
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "description": "A filter the endpoint cannot apply.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_region": {
                    "value": {
                      "error": "unknown_region",
                      "detail": "one of: US"
                    }
                  },
                  "unknown_license_group": {
                    "value": {
                      "error": "unknown_license_group",
                      "detail": "one of: Social Work, Counseling, Psychology, MFT, BCBA"
                    }
                  },
                  "bad_q": {
                    "value": {
                      "error": "bad_q",
                      "detail": "give q once"
                    }
                  },
                  "bad_query": {
                    "value": {
                      "error": "bad_query",
                      "detail": "query parameters cannot contain a NUL character"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/licenses?q=LCSW\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/coverage": {
      "get": {
        "tags": [
          "Reference lists"
        ],
        "operationId": "listCoverage",
        "summary": "List coverage",
        "description": "Every combination of jurisdiction and license group, covered or not, with its licenses and when anything in it last changed. The `summary` counts the rows returned. `license` and `q` belong to /licenses and are refused here.",
        "parameters": [
          {
            "$ref": "#/components/parameters/stateStrict"
          },
          {
            "$ref": "#/components/parameters/regionStrict"
          },
          {
            "$ref": "#/components/parameters/licenseGroupStrict"
          },
          {
            "$ref": "#/components/parameters/covered"
          }
        ],
        "responses": {
          "200": {
            "description": "Coverage rows and their summary.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data",
                    "summary"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CoverageRow"
                      }
                    },
                    "summary": {
                      "$ref": "#/components/schemas/CoverageSummary"
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "jurisdiction": {
                        "code": "CA",
                        "name": "California",
                        "region": "US",
                        "board": "Board of Behavioral Sciences"
                      },
                      "license_group": "Social Work",
                      "covered": true,
                      "licenses": [
                        "LCSW (Licensed Clinical Social Worker)"
                      ],
                      "last_changed_at": "2026-08-12T14:03:11.000Z"
                    }
                  ],
                  "summary": {
                    "combinations": 255,
                    "covered": 255,
                    "not_covered": 0
                  }
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "description": "A filter the endpoint cannot apply.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_region": {
                    "value": {
                      "error": "unknown_region",
                      "detail": "one of: US"
                    }
                  },
                  "unknown_license_group": {
                    "value": {
                      "error": "unknown_license_group",
                      "detail": "one of: Social Work, Counseling, Psychology, MFT, BCBA"
                    }
                  },
                  "bad_covered": {
                    "value": {
                      "error": "bad_covered",
                      "detail": "covered=true or covered=false"
                    }
                  },
                  "unsupported_filter": {
                    "value": {
                      "error": "unsupported_filter",
                      "detail": "license and q filter /v1/licenses; /v1/coverage filters by state, region, license_group and covered"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/coverage?state=CA\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/license-groups": {
      "get": {
        "tags": [
          "Reference lists"
        ],
        "operationId": "listLicenseGroups",
        "summary": "List license groups",
        "description": "The five license groups, with how many jurisdictions and licenses each covers now.",
        "parameters": [
          {
            "$ref": "#/components/parameters/regionStrict"
          }
        ],
        "responses": {
          "200": {
            "description": "The five groups in alphabetical order.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/LicenseGroupSummary"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "license_group": "Social Work",
                      "jurisdictions_covered": 51,
                      "licenses": 51
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "400": {
            "description": "An unknown region.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "unknown_region": {
                    "value": {
                      "error": "unknown_region",
                      "detail": "one of: US"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/license-groups\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/topics": {
      "get": {
        "tags": [
          "Reference lists"
        ],
        "operationId": "listTopics",
        "summary": "List topics",
        "description": "The canonical topic vocabulary. Boards name one subject many ways, so each topic has a key, a label and the alternate wordings that mean it. To resolve a record's `required_topics[].topic`, match it against each topic's `label` and `aliases` together, ignoring case and repeated spaces. Most wordings resolve; a few have no key yet.",
        "responses": {
          "200": {
            "description": "Topics in curated order.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Topic"
                      }
                    }
                  }
                },
                "example": {
                  "data": [
                    {
                      "key": "ethics",
                      "label": "Ethics",
                      "aliases": [
                        "Ethics and Jurisprudence",
                        "Ethical Practice of Psychology"
                      ]
                    }
                  ]
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/topics\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    },
    "/meta": {
      "get": {
        "tags": [
          "Reference lists"
        ],
        "operationId": "getMeta",
        "summary": "Get the dataset summary",
        "description": "Counts, when requirements last changed, and the closed value sets a client can validate against. `dataset.last_changed_at` moves when a requirement version is added, amended or retired. It does not move when a jurisdiction name or board is edited, so keep a scheduled full pull as well.",
        "responses": {
          "200": {
            "description": "The summary.",
            "headers": {
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "data"
                  ],
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Meta"
                    }
                  }
                },
                "example": {
                  "data": {
                    "api_version": "v1",
                    "dataset": {
                      "last_changed_at": "2026-08-12T14:03:11.000Z",
                      "jurisdictions": 51,
                      "jurisdictions_covered": 51,
                      "license_groups": 5,
                      "combinations": 255,
                      "combinations_covered": 255,
                      "current_records": 255,
                      "record_versions": 255
                    },
                    "values": {
                      "regions": [
                        "US"
                      ],
                      "license_groups": [
                        "BCBA",
                        "Counseling",
                        "MFT",
                        "Psychology",
                        "Social Work"
                      ],
                      "confidence": [
                        "high",
                        "medium",
                        "low",
                        "unverified"
                      ],
                      "change_types": [
                        "added",
                        "amended",
                        "retired"
                      ]
                    }
                  }
                }
              }
            }
          },
          "304": {
            "$ref": "#/components/responses/NotModified"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/PlanRequired"
          }
        },
        "x-codeSample": "curl -s \"https://api.verbena.health/v1/meta\" \\\n  -H \"Authorization: Bearer $VERBENA_API_KEY\""
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "vb_ key",
        "description": "An API key sent as `Authorization: Bearer vb_...`. Keys are read-only, shown once when issued, and expire. Keep them on your servers."
      }
    },
    "headers": {
      "ETag": {
        "description": "A weak validator for the response body. Send it back as `If-None-Match` to get 304 when nothing changed.",
        "schema": {
          "type": "string"
        }
      }
    },
    "parameters": {
      "state": {
        "name": "state",
        "in": "query",
        "description": "Jurisdiction codes, case-insensitive. Repeat the parameter or use a comma list: `state=CA,NY`.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "examples": [
              "CA"
            ]
          }
        },
        "style": "form",
        "explode": false
      },
      "region": {
        "name": "region",
        "in": "query",
        "description": "Regions. `US` is the only region served; any other value matches nothing.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "US"
            ]
          }
        },
        "style": "form",
        "explode": false
      },
      "license_group": {
        "name": "license_group",
        "in": "query",
        "description": "License groups, case-insensitive. Repeat the parameter or use a comma list.",
        "schema": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/LicenseGroup"
          }
        },
        "style": "form",
        "explode": false
      },
      "stateStrict": {
        "name": "state",
        "in": "query",
        "description": "Jurisdiction codes, case-insensitive. Repeat the parameter or use a comma list.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "style": "form",
        "explode": false
      },
      "regionStrict": {
        "name": "region",
        "in": "query",
        "description": "Regions, case-insensitive. `US` is the only one; anything else is `400 unknown_region`.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "US"
            ]
          }
        },
        "style": "form",
        "explode": false
      },
      "licenseGroupStrict": {
        "name": "license_group",
        "in": "query",
        "description": "License groups, case-insensitive. A value that is not one of the five is `400 unknown_license_group`.",
        "schema": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/LicenseGroup"
          }
        },
        "style": "form",
        "explode": false
      },
      "license": {
        "name": "license",
        "in": "query",
        "description": "An exact license label, matched case-insensitively. Repeat the parameter for several; labels can contain commas, so commas do not split.",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "examples": [
              "LCSW (Licensed Clinical Social Worker)"
            ]
          }
        },
        "style": "form",
        "explode": true
      },
      "q": {
        "name": "q",
        "in": "query",
        "description": "A case-insensitive substring of the license label, for example `LCSW`. Give it once.",
        "schema": {
          "type": "string"
        }
      },
      "confidence": {
        "name": "confidence",
        "in": "query",
        "description": "One confidence value.",
        "schema": {
          "$ref": "#/components/schemas/Confidence"
        }
      },
      "cpd": {
        "name": "cpd",
        "in": "query",
        "description": "`true` for regimes with no fixed hours, `false` for the rest.",
        "schema": {
          "type": "boolean"
        }
      },
      "fully_async_ok": {
        "name": "fully_async_ok",
        "in": "query",
        "description": "`true` for requirements with no live-session minimum, `false` for those with one.",
        "schema": {
          "type": "boolean"
        }
      },
      "as_of": {
        "name": "as_of",
        "in": "query",
        "description": "An ISO 8601 date or date-time. Returns the versions in force at that moment instead of the current ones.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "since": {
        "name": "since",
        "in": "query",
        "required": true,
        "description": "An ISO 8601 date or date-time. Inclusive.",
        "schema": {
          "type": "string",
          "format": "date-time"
        }
      },
      "include": {
        "name": "include",
        "in": "query",
        "description": "`all` adds changes to our own metadata; the default returns material changes only.",
        "schema": {
          "type": "string",
          "enum": [
            "all"
          ]
        }
      },
      "covered": {
        "name": "covered",
        "in": "query",
        "description": "`true` or `false` keeps one side; anything else is `400 bad_covered`.",
        "schema": {
          "type": "boolean"
        }
      },
      "limit": {
        "name": "limit",
        "in": "query",
        "description": "Page size, 1 to 200.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 200,
          "default": 50
        }
      },
      "cursor": {
        "name": "cursor",
        "in": "query",
        "description": "The `next_cursor` from the previous page.",
        "schema": {
          "type": "string"
        }
      },
      "statePath": {
        "name": "state",
        "in": "path",
        "required": true,
        "description": "A jurisdiction code, case-insensitive.",
        "schema": {
          "type": "string",
          "examples": [
            "CA"
          ]
        }
      },
      "licenseGroupPath": {
        "name": "license_group",
        "in": "path",
        "required": true,
        "description": "A license group, case-insensitive.",
        "schema": {
          "$ref": "#/components/schemas/LicenseGroup"
        }
      }
    },
    "responses": {
      "NotModified": {
        "description": "Not modified: the `If-None-Match` ETag still matches. No body."
      },
      "Unauthorized": {
        "description": "The key is missing, unknown, revoked or expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "missing_api_key": {
                "value": {
                  "error": "missing_api_key",
                  "detail": "Authorization: Bearer <key>"
                }
              },
              "invalid_api_key": {
                "value": {
                  "error": "invalid_api_key"
                }
              }
            }
          }
        }
      },
      "PlanRequired": {
        "description": "The key belongs to an account whose plan does not include API access.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "plan_required": {
                "value": {
                  "error": "plan_required",
                  "detail": "API access is part of the paid plan."
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "LicenseGroup": {
        "type": "string",
        "enum": [
          "Social Work",
          "Counseling",
          "Psychology",
          "MFT",
          "BCBA"
        ],
        "description": "One of five license groups."
      },
      "Confidence": {
        "type": "string",
        "enum": [
          "high",
          "medium",
          "low",
          "unverified"
        ],
        "description": "`high`: every core value was checked against a primary source and dated. `medium` or `low`: published with less certainty. `unverified`: not yet checked against its source."
      },
      "Jurisdiction": {
        "type": "object",
        "required": [
          "code",
          "name",
          "region",
          "board"
        ],
        "properties": {
          "code": {
            "type": "string",
            "description": "Jurisdiction code, for example `CA`."
          },
          "name": {
            "type": "string"
          },
          "region": {
            "type": "string",
            "enum": [
              "US"
            ]
          },
          "board": {
            "type": [
              "string",
              "null"
            ],
            "description": "The licensing board, where known."
          }
        }
      },
      "JurisdictionWithGroups": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Jurisdiction"
          },
          {
            "type": "object",
            "required": [
              "license_groups"
            ],
            "properties": {
              "license_groups": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LicenseGroup"
                },
                "description": "Groups with current data, each listed once."
              }
            }
          }
        ]
      },
      "RequiredTopic": {
        "type": "object",
        "required": [
          "topic"
        ],
        "properties": {
          "topic": {
            "type": "string",
            "description": "The board's wording. Resolve it with /topics."
          },
          "hours": {
            "type": [
              "number",
              "null"
            ],
            "description": "Hours required for the topic, where the board states a number."
          },
          "note": {
            "type": "string",
            "description": "When it applies, for example every renewal or the first renewal only."
          }
        }
      },
      "Requirement": {
        "type": "object",
        "description": "The continuing education rule for one license in one jurisdiction, as one version.",
        "required": [
          "jurisdiction",
          "license_group",
          "license",
          "cpd",
          "total_hours",
          "cycle_years",
          "live_interactive_required_hours",
          "fully_async_ok",
          "home_study_cap",
          "required_topics",
          "board_nuances",
          "source_urls",
          "confidence",
          "verified_at",
          "effective_from",
          "effective_to",
          "is_current",
          "ingested_at"
        ],
        "properties": {
          "jurisdiction": {
            "$ref": "#/components/schemas/Jurisdiction"
          },
          "license_group": {
            "$ref": "#/components/schemas/LicenseGroup"
          },
          "license": {
            "type": "string",
            "description": "The license label, usually the abbreviation then the full name. With the jurisdiction code and license group, it identifies the record across versions."
          },
          "cpd": {
            "type": "boolean",
            "description": "Derived: true when `total_hours` is null, a regime with no fixed hours."
          },
          "total_hours": {
            "type": [
              "number",
              "null"
            ],
            "description": "Hours per renewal cycle. Null means no fixed hours, not missing data."
          },
          "cycle_years": {
            "type": [
              "number",
              "null"
            ],
            "description": "Length of the renewal cycle in years."
          },
          "live_interactive_required_hours": {
            "type": "number",
            "description": "The minimum hours that must be live or interactive."
          },
          "fully_async_ok": {
            "type": "boolean",
            "description": "Derived: true when there is no live minimum."
          },
          "home_study_cap": {
            "type": [
              "string",
              "null"
            ],
            "description": "The board's statement on self-study limits, as plain text."
          },
          "required_topics": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RequiredTopic"
            }
          },
          "board_nuances": {
            "type": [
              "string",
              "null"
            ],
            "description": "The board's own notes: exemptions, deadlines and anything that does not fit a number."
          },
          "source_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "description": "Where the rule is published. Every record has at least one."
          },
          "confidence": {
            "$ref": "#/components/schemas/Confidence"
          },
          "verified_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When the values were last checked against their source."
          },
          "effective_from": {
            "type": "string",
            "format": "date-time",
            "description": "When this version was recorded. Not the board's effective date; that is in the notes where the board states one."
          },
          "effective_to": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "When this version was closed; null while it is in force."
          },
          "is_current": {
            "type": "boolean"
          },
          "ingested_at": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "Change": {
        "type": "object",
        "required": [
          "jurisdiction",
          "jurisdiction_name",
          "region",
          "license_group",
          "license",
          "change_type",
          "material",
          "event_at",
          "diff",
          "current"
        ],
        "properties": {
          "jurisdiction": {
            "type": "string",
            "description": "Jurisdiction code."
          },
          "jurisdiction_name": {
            "type": "string"
          },
          "region": {
            "type": "string",
            "enum": [
              "US"
            ]
          },
          "license_group": {
            "$ref": "#/components/schemas/LicenseGroup"
          },
          "license": {
            "type": "string"
          },
          "change_type": {
            "type": "string",
            "enum": [
              "added",
              "amended",
              "retired"
            ]
          },
          "material": {
            "type": "boolean",
            "description": "True when a requirement was added or retired, or a rule field or the board notes moved."
          },
          "event_at": {
            "type": "string",
            "format": "date-time",
            "description": "`effective_from` for added and amended rows, `effective_to` for retired ones."
          },
          "diff": {
            "type": [
              "object",
              "null"
            ],
            "description": "For `amended` rows, each changed field as `{from, to}`. Keys use storage names: `live_hours` is `live_interactive_required_hours` on the record.",
            "additionalProperties": {
              "type": "object",
              "properties": {
                "from": {},
                "to": {}
              }
            }
          },
          "current": {
            "$ref": "#/components/schemas/Requirement"
          }
        }
      },
      "License": {
        "type": "object",
        "required": [
          "jurisdiction",
          "license_group",
          "license",
          "last_changed_at"
        ],
        "properties": {
          "jurisdiction": {
            "$ref": "#/components/schemas/Jurisdiction"
          },
          "license_group": {
            "$ref": "#/components/schemas/LicenseGroup"
          },
          "license": {
            "type": "string"
          },
          "last_changed_at": {
            "type": "string",
            "format": "date-time",
            "description": "When this license's current version took effect."
          }
        }
      },
      "CoverageRow": {
        "type": "object",
        "required": [
          "jurisdiction",
          "license_group",
          "covered",
          "licenses",
          "last_changed_at"
        ],
        "properties": {
          "jurisdiction": {
            "$ref": "#/components/schemas/Jurisdiction"
          },
          "license_group": {
            "$ref": "#/components/schemas/LicenseGroup"
          },
          "covered": {
            "type": "boolean"
          },
          "licenses": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Current licenses in the combination, sorted; empty when not covered."
          },
          "last_changed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "The latest addition, amendment or retirement in the combination; null if it never had a record."
          }
        }
      },
      "CoverageSummary": {
        "type": "object",
        "required": [
          "combinations",
          "covered",
          "not_covered"
        ],
        "properties": {
          "combinations": {
            "type": "integer"
          },
          "covered": {
            "type": "integer"
          },
          "not_covered": {
            "type": "integer"
          }
        }
      },
      "LicenseGroupSummary": {
        "type": "object",
        "required": [
          "license_group",
          "jurisdictions_covered",
          "licenses"
        ],
        "properties": {
          "license_group": {
            "$ref": "#/components/schemas/LicenseGroup"
          },
          "jurisdictions_covered": {
            "type": "integer"
          },
          "licenses": {
            "type": "integer"
          }
        }
      },
      "Topic": {
        "type": "object",
        "required": [
          "key",
          "label",
          "aliases"
        ],
        "properties": {
          "key": {
            "type": "string",
            "pattern": "^[a-z0-9_]+$"
          },
          "label": {
            "type": "string"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Other wordings boards use for the topic."
          }
        }
      },
      "Meta": {
        "type": "object",
        "required": [
          "api_version",
          "dataset",
          "values"
        ],
        "properties": {
          "api_version": {
            "type": "string",
            "enum": [
              "v1"
            ]
          },
          "dataset": {
            "type": "object",
            "required": [
              "last_changed_at",
              "jurisdictions",
              "jurisdictions_covered",
              "license_groups",
              "combinations",
              "combinations_covered",
              "current_records",
              "record_versions"
            ],
            "properties": {
              "last_changed_at": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "jurisdictions": {
                "type": "integer"
              },
              "jurisdictions_covered": {
                "type": "integer"
              },
              "license_groups": {
                "type": "integer"
              },
              "combinations": {
                "type": "integer"
              },
              "combinations_covered": {
                "type": "integer"
              },
              "current_records": {
                "type": "integer"
              },
              "record_versions": {
                "type": "integer"
              }
            }
          },
          "values": {
            "type": "object",
            "required": [
              "regions",
              "license_groups",
              "confidence",
              "change_types"
            ],
            "properties": {
              "regions": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "license_groups": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/LicenseGroup"
                }
              },
              "confidence": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Confidence"
                }
              },
              "change_types": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "string",
            "description": "A stable code to branch on."
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation. Do not parse it."
          },
          "jurisdiction": {
            "type": "string",
            "description": "On `unknown_jurisdiction`, the code that was not found."
          }
        }
      }
    }
  }
}
