diff --git a/cmd/cve/main.go b/cmd/cve/main.go
new file mode 100644
index 0000000..f70799e
--- /dev/null
+++ b/cmd/cve/main.go
@@ -0,0 +1,212 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Command cve provides utilities for managing CVE IDs and CVE Records via the
+// MITRE CVE Services API.
+package main
+
+import (
+	"errors"
+	"flag"
+	"fmt"
+	"log"
+	"os"
+	"regexp"
+	"time"
+
+	"golang.org/x/vulndb/internal/cveclient"
+)
+
+var (
+	apiKey = flag.String("key",
+		os.Getenv("CVE_API_KEY"), "key for accessing the CVE API (can also be set via env var CVE_API_KEY)")
+	apiUser = flag.String("user",
+		os.Getenv("CVE_API_USER"), "username for accessing the CVE API (can also be set via env var CVE_API_USER)")
+	apiOrg = flag.String("org",
+		"Go", "organization name for accessing the CVE API")
+	test = flag.Bool("test", false, "whether to access the CVE API in the test environment")
+
+	// flags for the reserve command
+	reserveN          = flag.Int("n", 1, "reserve: the number of new CVE IDs to reserve")
+	reserveSequential = flag.Bool("seq", true, "reserve: if true, reserve new CVE ID batches in sequence")
+
+	// flags for the list command
+	listState = flag.String("state", "", "list: filter by CVE state (RESERVED, PUBLIC, or REJECT)")
+
+	// flags that apply to multiple commands
+	year = flag.Int("year", 0, "reserve: the CVE ID year for newly reserved CVE IDs (default is current year)\nlist: filter by the year in the CVE ID")
+)
+
+func main() {
+	out := flag.CommandLine.Output()
+	flag.Usage = func() {
+		fmt.Fprintln(out, "Command cve provides utilities for managing CVE IDs and CVE Records via the MITRE CVE Services API")
+		formatCmd := "    %s: %s\n"
+		fmt.Fprintf(out, "usage: cve [-key] [-user] [-org] [-test] <cmd> ...\n  commands:\n")
+		fmt.Fprintf(out, formatCmd, "[-n] [-seq] [-year] reserve", "reserves new CVE IDs")
+		fmt.Fprintf(out, formatCmd, "quota", "outputs the CVE ID quota of an organization")
+		fmt.Fprintf(out, formatCmd, "lookup {cve-id}", "outputs details on an assigned CVE ID (CVE-YYYY-NNNN)")
+		fmt.Fprintf(out, formatCmd, "[-year] [-state] list", "lists all CVE IDs for an organization")
+		flag.PrintDefaults()
+	}
+
+	flag.Parse()
+	if flag.NArg() < 1 {
+		logUsageErr("cve", fmt.Errorf("must provide subcommand"))
+	}
+
+	// The cve tool does not currently support the dev endpoint as there is
+	// no clear use case for us.
+	endpoint := cveclient.ProdEndpoint
+	if *test {
+		endpoint = cveclient.TestEndpoint
+	}
+
+	if *apiKey == "" {
+		logUsageErr("cve", errors.New("the CVE API key (flag -key or env var CVE_API_KEY) must be set"))
+	}
+	if *apiUser == "" {
+		logUsageErr("cve", errors.New("the CVE API user (flag -user or env var CVE_API_USER) must be set"))
+	}
+
+	cfg := cveclient.Config{
+		Endpoint: endpoint,
+		Key:      *apiKey,
+		Org:      *apiOrg,
+		User:     *apiUser,
+	}
+	c := cveclient.New(cfg)
+
+	cmd := flag.Arg(0)
+	switch cmd {
+	case "help":
+		flag.Usage()
+	case "reserve":
+		year := *year
+		if year == 0 {
+			year = getCurrentYear()
+		}
+		mode := cveclient.SequentialRequest
+		if !*reserveSequential {
+			mode = cveclient.NonsequentialRequest
+		}
+		if err := reserve(c, cveclient.ReserveOptions{
+			NumIDs: *reserveN,
+			Year:   year,
+			Mode:   mode,
+		}); err != nil {
+			log.Fatalf("cve reserve: could not reserve any new CVEs due to error:\n  %v", err)
+		}
+	case "quota":
+		if err := quota(c); err != nil {
+			log.Fatalf("cve quota: could not retrieve quota info due to error:\n  %v", err)
+		}
+	case "lookup":
+		id, err := validateID(flag.Arg(1))
+		if err != nil {
+			logUsageErr("cve lookup", err)
+		}
+		if err := lookup(c, id); err != nil {
+			log.Fatalf("cve lookup: could not retrieve CVE IDs due to error:\n  %v", err)
+		}
+	case "list":
+		// TODO(http://go.dev/issues/53258): allow time-based filters via flags.
+		var filters *cveclient.ListOptions
+		if *listState != "" || *year != 0 {
+			filters = new(cveclient.ListOptions)
+			state, err := validateState(*listState)
+			if err != nil {
+				logUsageErr("cve list", err)
+			}
+			filters.State = state
+			filters.Year = *year
+		}
+		if err := list(c, filters); err != nil {
+			log.Fatalf("cve list: could not retrieve CVE IDs due to error:\n  %v", err)
+		}
+	default:
+		logUsageErr("cve", fmt.Errorf("unsupported command: %q", cmd))
+	}
+}
+
+func logUsageErr(context string, err error) {
+	log.Printf("%s: %s\n\n", context, err)
+	flag.Usage()
+	os.Exit(1)
+}
+
+func getCurrentYear() int {
+	year, _, _ := time.Now().Date()
+	return year
+}
+
+var cveRegex = regexp.MustCompile(`^CVE-\d{4}-\d{4,}$`)
+
+func validateID(id string) (string, error) {
+	if id == "" {
+		return "", errors.New("CVE ID must be provided")
+	}
+	if !cveRegex.MatchString(id) {
+		return "", fmt.Errorf("%q is not a valid CVE ID", id)
+	}
+	return id, nil
+}
+
+var stateRegex = regexp.MustCompile(`^(RESERVED|PUBLIC|REJECT)$`)
+
+func validateState(state string) (string, error) {
+	if state != "" && !stateRegex.MatchString(state) {
+		return "", fmt.Errorf("state must match regex %v", stateRegex)
+	}
+	return state, nil
+}
+
+func reserve(c *cveclient.Client, opts cveclient.ReserveOptions) error {
+	cves, err := c.ReserveIDs(opts)
+	if err != nil {
+		return err
+	}
+	cvesReserved := len(cves)
+	if cvesReserved < opts.NumIDs {
+		fmt.Printf("warning: only %d of %d requested CVE IDs were reserved\n",
+			len(cves), opts.NumIDs)
+	}
+	fmt.Printf("successfully reserved %d CVE IDs:\n  %v\n", cvesReserved, cves.ShortString())
+	return nil
+}
+
+func quota(c *cveclient.Client) error {
+	quota, err := c.RetrieveQuota()
+	if err != nil {
+		return err
+	}
+	fmt.Printf("quota info for org %q:\n  quota: %d\n  total reserved: %d\n  available:  %d\n", c.Org, quota.Quota, quota.Reserved, quota.Available)
+	return nil
+}
+
+func lookup(c *cveclient.Client, id string) error {
+	cve, err := c.RetrieveCVE(id)
+	if err != nil {
+		return err
+	}
+	fmt.Println(cve)
+	return nil
+}
+
+func list(c *cveclient.Client, lf *cveclient.ListOptions) error {
+	cves, err := c.ListOrgCVEs(lf)
+	if err != nil {
+		return err
+	}
+	var filterString string
+	if lf != nil {
+		filterString = fmt.Sprintf(" with filters %s", lf)
+	}
+	if n := len(cves); n > 0 {
+		fmt.Printf("found %d CVE IDs for org %q%s:\n%v\n", n, c.Org, filterString, cves)
+	} else {
+		fmt.Printf("found no CVE IDs for org %q%s\n", c.Org, filterString)
+	}
+	return nil
+}
diff --git a/internal/cveclient/cveclient.go b/internal/cveclient/cveclient.go
new file mode 100644
index 0000000..0c22fb9
--- /dev/null
+++ b/internal/cveclient/cveclient.go
@@ -0,0 +1,378 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package cveclient implements a client for interacting with MITRE CVE
+// Services API as described at https://cveawg.mitre.org/api-docs/openapi.json.
+package cveclient
+
+import (
+	"encoding/json"
+	"fmt"
+	"io"
+	"net/http"
+	"net/url"
+	"strconv"
+	"strings"
+	"time"
+)
+
+const (
+	// ProdEndpoint is the production endpoint
+	ProdEndpoint = "https://cveawg.mitre.org"
+	// TestEndpoint is the test endpoint
+	TestEndpoint = "https://cveawg-test.mitre.org"
+	// DevEndpoint is the dev endpoint
+	DevEndpoint = "https://cveawg-dev.mitre.org"
+)
+
+// Client is a MITRE CVE Services API client.
+type Client struct {
+	Config
+	c *http.Client
+}
+
+// Config contains client configuration data.
+type Config struct {
+	// Endpoint is the endpoint to access when making API calls. Required.
+	Endpoint string
+	// Org is the shortname for the organization that is authenticated when
+	// making API calls. Required.
+	Org string
+	// Key is the user's API key. Required.
+	Key string
+	// User is the username for the account that is making API calls. Required.
+	User string
+}
+
+// New returns an initialized client configured via cfg.
+func New(cfg Config) *Client {
+	return &Client{cfg, http.DefaultClient}
+}
+
+// AssignedCVE contains information about an assigned CVE.
+type AssignedCVE struct {
+	ID          string      `json:"cve_id"`
+	Year        string      `json:"cve_year"`
+	State       string      `json:"state"`
+	CNA         string      `json:"owning_cna"`
+	Reserved    time.Time   `json:"reserved"`
+	RequestedBy RequestedBy `json:"requested_by"`
+}
+
+// RequestedBy indicates the requesting user and organization for a CVE.
+type RequestedBy struct {
+	CNA  string `json:"cna"`
+	User string `json:"user"`
+}
+
+func (c AssignedCVE) String() string {
+	return fmt.Sprintf("%s: state=%s, cna=%s, requester=%s", c.ID, c.State, c.CNA, c.RequestedBy.User)
+}
+
+// AssignedCVEList is a list of AssignedCVEs.
+type AssignedCVEList []AssignedCVE
+
+// ShortString outputs a formatted string of comma-separated CVE IDs.
+func (cs AssignedCVEList) ShortString() string {
+	strs := []string{}
+	for _, c := range cs {
+		strs = append(strs, c.ID)
+	}
+	return strings.Join(strs, ", ")
+}
+
+// String outputs a formatted string of newline-separated CVE data.
+func (cs AssignedCVEList) String() string {
+	strs := []string{}
+	for _, c := range cs {
+		strs = append(strs, c.String())
+	}
+	return strings.Join(strs, "\n")
+}
+
+// ReserveOptions contains the configuration options for reserving new
+// CVE IDs.
+type ReserveOptions struct {
+	// NumIDs is the the number of CVE IDs to reserve. Required.
+	NumIDs int
+	// Year is the CVE ID year for new IDs, indicating the year the
+	// vulnerability was discovered. Required.
+	Year int
+	// Mode indicates whether the block of CVEs should be in sequence.
+	// Relevant only if NumIDs > 1.
+	Mode RequestType
+}
+
+// RequestType is the type of CVE ID reserve request.
+type RequestType string
+
+const (
+	// SequentialRequest requests CVE IDs be reserved in a sequential fashion.
+	SequentialRequest RequestType = "sequential"
+	// NonsequentialRequest requests CVE IDs be reserved in a nonsequential fashion.
+	NonsequentialRequest RequestType = "nonsequential"
+)
+
+func (o *ReserveOptions) getURLParams(org string) url.Values {
+	params := url.Values{}
+	params.Set("amount", fmt.Sprint(o.NumIDs))
+	if o.Year != 0 {
+		params.Set("cve_year", strconv.Itoa(o.Year))
+	}
+	params.Set("short_name", org)
+	if o.NumIDs > 1 {
+		params.Set("batch_type", string(o.Mode))
+	}
+	return params
+}
+
+func (c *Client) createReserveIDsRequest(opts ReserveOptions) (*http.Request, error) {
+	req, err := c.createRequest(http.MethodPost,
+		fmt.Sprintf("%s/api/cve-id", c.Endpoint))
+	if err != nil {
+		return nil, err
+	}
+	req.URL.RawQuery = opts.getURLParams(c.Org).Encode()
+	return req, nil
+}
+
+type reserveIDsResponse struct {
+	CVEs AssignedCVEList `json:"cve_ids"`
+}
+
+// ReserveIDs sends a request to the CVE API to reserve a block of CVE IDs.
+// Returns a list of the reserved CVE IDs and their associated data.
+// There may be fewer IDs than requested if, for example, the organization's
+// quota is reached.
+func (c *Client) ReserveIDs(opts ReserveOptions) (AssignedCVEList, error) {
+	req, err := c.createReserveIDsRequest(opts)
+	if err != nil {
+		return nil, err
+	}
+	var assigned reserveIDsResponse
+	checkStatus := func(s int) bool {
+		return s == http.StatusOK || s == http.StatusPartialContent
+	}
+	err = c.sendRequest(req, checkStatus, &assigned)
+	if err != nil {
+		return nil, err
+	}
+	return assigned.CVEs, nil
+}
+
+// Quota contains information about an organizations reservation quota.
+type Quota struct {
+	Quota     int `json:"id_quota"`
+	Reserved  int `json:"total_reserved"`
+	Available int `json:"available"`
+}
+
+// RetrieveQuota queries the API for the organizations reservation quota.
+func (c *Client) RetrieveQuota() (Quota, error) {
+	req, err := c.createRequest(http.MethodGet, fmt.Sprintf("%s/api/org/%s/id_quota", c.Endpoint, c.Org))
+	if err != nil {
+		return Quota{}, err
+	}
+
+	var q Quota
+	err = c.sendRequest(req, nil, &q)
+	if err != nil {
+		return Quota{}, err
+	}
+	return q, nil
+}
+
+// RetrieveCVE requests information about an assigned CVE ID.
+func (c *Client) RetrieveCVE(id string) (AssignedCVE, error) {
+	req, err := c.createRequest(http.MethodGet, fmt.Sprintf("%s/api/cve-id/%s", c.Endpoint, id))
+	if err != nil {
+		return AssignedCVE{}, err
+	}
+
+	var cve AssignedCVE
+	err = c.sendRequest(req, nil, &cve)
+	if err != nil {
+		return AssignedCVE{}, err
+	}
+	return cve, nil
+}
+
+// ListOptions contains filters to be used when requesting a list of
+// assigned CVEs.
+type ListOptions struct {
+	State          string
+	Year           int
+	ReservedBefore *time.Time
+	ReservedAfter  *time.Time
+	ModifiedBefore *time.Time
+	ModifiedAfter  *time.Time
+}
+
+func (o ListOptions) String() string {
+	var s []string
+	if o.State != "" {
+		s = append(s, fmt.Sprintf("state=%s", o.State))
+	}
+	if o.Year != 0 {
+		s = append(s, fmt.Sprintf("year=%d", o.Year))
+	}
+	if o.ReservedBefore != nil {
+		s = append(s, fmt.Sprintf("reserved_before=%s", o.ReservedBefore.Format(time.RFC3339)))
+	}
+	if o.ReservedAfter != nil {
+		s = append(s, fmt.Sprintf("reserved_after=%s", o.ReservedAfter.Format(time.RFC3339)))
+	}
+	if o.ModifiedBefore != nil {
+		s = append(s, fmt.Sprintf("modified_before=%s", o.ModifiedBefore.Format(time.RFC3339)))
+	}
+	if o.ModifiedAfter != nil {
+		s = append(s, fmt.Sprintf("modified_after=%s", o.ModifiedAfter.Format(time.RFC3339)))
+	}
+	return strings.Join(s, ", ")
+}
+
+func (o *ListOptions) getURLParams() url.Values {
+	params := url.Values{}
+	if o.State != "" {
+		params.Set("state", o.State)
+	}
+	if o.Year != 0 {
+		params.Set("cve_id_year", strconv.Itoa(o.Year))
+	}
+	if o.ReservedBefore != nil {
+		params.Set("time_reserved.lt", o.ReservedBefore.Format(time.RFC3339))
+	}
+	if o.ReservedAfter != nil {
+		params.Set("time_reserved.gt", o.ReservedAfter.Format(time.RFC3339))
+	}
+	if o.ModifiedBefore != nil {
+		params.Set("time_modified.lt", o.ModifiedBefore.Format(time.RFC3339))
+	}
+	if o.ModifiedAfter != nil {
+		params.Set("time_modified.gt", o.ModifiedAfter.Format(time.RFC3339))
+	}
+	return params
+}
+
+type listOrgCVEsResponse struct {
+	CurrentPage int             `json:"currentPage"`
+	NextPage    int             `json:"nextPage"`
+	CVEs        AssignedCVEList `json:"cve_ids"`
+}
+
+func (c Client) createListOrgCVEsRequest(opts *ListOptions, page int) (*http.Request, error) {
+	req, err := c.createRequest(http.MethodGet, fmt.Sprintf("%s/api/cve-id", c.Endpoint))
+	if err != nil {
+		return nil, err
+	}
+	params := url.Values{}
+	if opts != nil {
+		params = opts.getURLParams()
+	}
+	if page > 0 {
+		params.Set("page", fmt.Sprint(page))
+	}
+	req.URL.RawQuery = params.Encode()
+	return req, nil
+}
+
+// ListOrgCVEs requests information about the CVEs the organization has been
+// assigned. This list can be filtered by setting the fields in opts.
+func (c *Client) ListOrgCVEs(opts *ListOptions) (AssignedCVEList, error) {
+	var cves []AssignedCVE
+	page := 0
+	for {
+		req, err := c.createListOrgCVEsRequest(opts, page)
+		if err != nil {
+			return nil, err
+		}
+		var result listOrgCVEsResponse
+		err = c.sendRequest(req, nil, &result)
+		if err != nil {
+			return nil, err
+		}
+		cves = append(cves, result.CVEs...)
+		if result.NextPage <= result.CurrentPage {
+			break
+		}
+		page = result.NextPage
+	}
+	return cves, nil
+}
+
+var (
+	headerApiUser = "CVE-API-USER"
+	headerApiOrg  = "CVE-API-ORG"
+	headerApiKey  = "CVE-API-KEY"
+)
+
+// createRequest creates a new HTTP request and sets the header fields.
+func (c *Client) createRequest(method, url string) (*http.Request, error) {
+	req, err := http.NewRequest(method, url, nil)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set(headerApiUser, c.User)
+	req.Header.Set(headerApiOrg, c.Org)
+	req.Header.Set(headerApiKey, c.Key)
+	return req, nil
+}
+
+// sendRequest sends an HTTP request, checks the returned status via
+// checkStatus, and attempts to unmarshal the response into result.
+// if checkStatus is nil, checks for http.StatusOK.
+func (c *Client) sendRequest(req *http.Request, checkStatus func(int) bool, result any) (err error) {
+	resp, err := c.c.Do(req)
+	if err != nil {
+		return fmt.Errorf("could not send HTTP request: %v", err)
+	}
+	defer resp.Body.Close()
+	if checkStatus == nil {
+		checkStatus = func(s int) bool {
+			return s == http.StatusOK
+		}
+	}
+	if !checkStatus(resp.StatusCode) {
+		return fmt.Errorf("HTTP request %s %q returned error: %w", req.Method, req.URL, extractError(resp))
+	}
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		return err
+	}
+	if err := json.Unmarshal(body, result); err != nil {
+		return err
+	}
+	return nil
+}
+
+type apiError struct {
+	Error   string `json:"error"`
+	Message string `json:"message"`
+}
+
+// extractError extracts additional error messages from the HTTP response
+// if available, and wraps them into a single error.
+func extractError(resp *http.Response) error {
+	errMsg := resp.Status
+	body, err := io.ReadAll(resp.Body)
+	if err != nil {
+		// Discard the read error and return the HTTP status.
+		return fmt.Errorf(errMsg)
+	}
+	var apiErr apiError
+	if err := json.Unmarshal(body, &apiErr); err != nil {
+		// Discard the unmarshal error and return the HTTP status.
+		return fmt.Errorf(errMsg)
+	}
+
+	// Append the error and message text if they add extra information
+	// beyond the HTTP status text.
+	statusText := strings.ToLower(http.StatusText(resp.StatusCode))
+	for _, errText := range []string{apiErr.Error, apiErr.Message} {
+		if errText != "" && strings.ToLower(errText) != statusText {
+			errMsg = fmt.Sprintf("%s: %s", errMsg, errText)
+		}
+	}
+	return fmt.Errorf(errMsg)
+}
diff --git a/internal/cveclient/cveclient_test.go b/internal/cveclient/cveclient_test.go
new file mode 100644
index 0000000..b637807
--- /dev/null
+++ b/internal/cveclient/cveclient_test.go
@@ -0,0 +1,402 @@
+// Copyright 2022 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package cveclient
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+	"net/http/httptest"
+	"net/url"
+	"reflect"
+	"strconv"
+	"strings"
+	"testing"
+	"time"
+
+	"golang.org/x/vulndb/internal/cveschema"
+)
+
+var (
+	testApiKey  = "test_api_key"
+	testApiOrg  = "test_api_org"
+	testApiUser = "test_api_user"
+)
+
+var defaultTestCVE = newTestCVE("CVE-2022-0000", cveschema.StateReserved, "2022")
+var defaultTestCVEs = AssignedCVEList{
+	defaultTestCVE, newTestCVE("CVE-2022-0001", cveschema.StateReserved, "2022"),
+}
+var defaultTestQuota = Quota{
+	Quota:     10,
+	Reserved:  3,
+	Available: 7,
+}
+
+var (
+	testTime2022 = time.Date(2022, 1, 1, 0, 0, 0, 0, time.UTC)
+	testTime2000 = time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC)
+	testTime1999 = time.Date(1999, 1, 1, 0, 0, 0, 0, time.UTC)
+	testTime1992 = time.Date(1992, 1, 1, 0, 0, 0, 0, time.UTC)
+)
+
+func newTestCVE(id, state, year string) AssignedCVE {
+	return AssignedCVE{
+		ID:       id,
+		Year:     year,
+		State:    state,
+		CNA:      testApiOrg,
+		Reserved: testTime2022,
+		RequestedBy: RequestedBy{
+			CNA:  testApiOrg,
+			User: testApiUser,
+		},
+	}
+}
+
+func newTestClientAndServer(handler http.HandlerFunc) (*Client, *httptest.Server) {
+	s := httptest.NewServer(http.HandlerFunc(handler))
+	c := New(Config{
+		Endpoint: s.URL,
+		Key:      testApiKey,
+		Org:      testApiOrg,
+		User:     testApiUser})
+	c.c = s.Client()
+	return c, s
+}
+
+func checkHeaders(t *testing.T, r *http.Request) {
+	if got, want := r.Header.Get(headerApiUser), testApiUser; got != want {
+		t.Errorf("HTTP Header %q = %s, want %s", headerApiUser, got, want)
+	}
+	if got, want := r.Header.Get(headerApiOrg), testApiOrg; got != want {
+		t.Errorf("HTTP Header %q = %s, want %s", headerApiOrg, got, want)
+	}
+	if got, want := r.Header.Get(headerApiKey), testApiKey; got != want {
+		t.Errorf("HTTP Header %q = %s, want %s", headerApiKey, got, want)
+	}
+}
+
+func newTestHandler(t *testing.T, mockStatus int, mockResponse any, validateRequest func(t *testing.T, r *http.Request)) http.HandlerFunc {
+	mr, err := json.Marshal(mockResponse)
+	if err != nil {
+		t.Fatalf("could not marshal mock response: %v", err)
+	}
+	return func(w http.ResponseWriter, r *http.Request) {
+		if validateRequest != nil {
+			validateRequest(t, r)
+		}
+		checkHeaders(t, r)
+		w.WriteHeader(mockStatus)
+		w.Write(mr)
+	}
+}
+
+func newTestHandlerMultiPage(t *testing.T, mockResponses []any, validateRequest func(t *testing.T, r *http.Request)) http.HandlerFunc {
+	var mrs [][]byte
+	for _, r := range mockResponses {
+		mr, err := json.Marshal(r)
+		if err != nil {
+			t.Fatalf("could not marshal mock response: %v", err)
+		}
+		mrs = append(mrs, mr)
+	}
+	return func(w http.ResponseWriter, r *http.Request) {
+		if validateRequest != nil {
+			validateRequest(t, r)
+		}
+		parsed, err := url.ParseQuery(r.URL.RawQuery)
+		if err != nil {
+			t.Fatalf("could not parse URL query: %v", err)
+		}
+		var page int
+		if pages := parsed["page"]; len(pages) >= 1 {
+			page, err = strconv.Atoi(parsed["page"][0])
+			if err != nil {
+				t.Fatalf("could not parse page as int: %v", err)
+			}
+		}
+		checkHeaders(t, r)
+		w.WriteHeader(http.StatusOK)
+		w.Write(mrs[page])
+	}
+}
+
+func TestCreateReserveIDsRequest(t *testing.T) {
+	tests := []struct {
+		opts       ReserveOptions
+		wantParams string
+	}{
+		{
+			opts: ReserveOptions{
+				NumIDs: 1,
+				Year:   2000,
+				Mode:   SequentialRequest,
+			},
+			wantParams: "amount=1&cve_year=2000&short_name=test_api_org",
+		},
+		{
+			opts: ReserveOptions{
+				NumIDs: 2,
+				Year:   2022,
+				Mode:   SequentialRequest,
+			},
+			wantParams: "amount=2&batch_type=sequential&cve_year=2022&short_name=test_api_org",
+		},
+		{
+			opts: ReserveOptions{
+				NumIDs: 3,
+				Year:   2010,
+				Mode:   NonsequentialRequest,
+			},
+			wantParams: "amount=3&batch_type=nonsequential&cve_year=2010&short_name=test_api_org",
+		},
+	}
+	for _, test := range tests {
+		t.Run(fmt.Sprintf("NumIDs=%d/Year=%d/Mode=%s", test.opts.NumIDs, test.opts.Year, test.opts.Mode), func(t *testing.T) {
+			c, s := newTestClientAndServer(nil)
+			defer s.Close()
+			req, err := c.createReserveIDsRequest(test.opts)
+			if err != nil {
+				t.Fatalf("unexpected error getting reserve ID request: %v", err)
+			}
+			if got, want := req.URL.RawQuery, test.wantParams; got != want {
+				t.Errorf("incorrect request params: got %v, want %v", got, want)
+			}
+		})
+	}
+}
+
+type queryFunc func(c *Client) (any, error)
+
+var (
+	reserveIDsQuery = func(c *Client) (any, error) {
+		return c.ReserveIDs(ReserveOptions{
+			NumIDs: 2,
+			Year:   2002,
+			Mode:   SequentialRequest,
+		})
+	}
+	retrieveQuotaQuery = func(c *Client) (any, error) {
+		return c.RetrieveQuota()
+	}
+	retrieveCVEQuery = func(c *Client) (any, error) {
+		return c.RetrieveCVE(defaultTestCVE.ID)
+	}
+	listOrgCVEsQuery = func(c *Client) (any, error) {
+		return c.ListOrgCVEs(&ListOptions{})
+	}
+)
+
+func TestAllSuccess(t *testing.T) {
+	tests := []struct {
+		name           string
+		mockStatus     int
+		mockResponse   any
+		query          queryFunc
+		wantHTTPMethod string
+		wantPath       string
+		want           any
+	}{
+		{
+			name:       "ReserveIDs",
+			query:      reserveIDsQuery,
+			mockStatus: http.StatusOK,
+			mockResponse: reserveIDsResponse{
+				CVEs: defaultTestCVEs},
+			wantHTTPMethod: http.MethodPost,
+			wantPath:       "/api/cve-id",
+			want:           defaultTestCVEs,
+		},
+		{
+			name:       "ReserveIDs/partial content ok",
+			query:      reserveIDsQuery,
+			mockStatus: http.StatusPartialContent,
+			mockResponse: reserveIDsResponse{
+				CVEs: AssignedCVEList{defaultTestCVE}},
+			wantHTTPMethod: http.MethodPost,
+			wantPath:       "/api/cve-id",
+			want:           AssignedCVEList{defaultTestCVE},
+		},
+		{
+			name:           "RetrieveQuota",
+			query:          retrieveQuotaQuery,
+			mockStatus:     http.StatusOK,
+			mockResponse:   defaultTestQuota,
+			wantHTTPMethod: http.MethodGet,
+			wantPath:       "/api/org/test_api_org/id_quota",
+			want:           defaultTestQuota,
+		},
+		{
+			name:           "RetrieveCVE",
+			query:          retrieveCVEQuery,
+			mockStatus:     http.StatusOK,
+			mockResponse:   defaultTestCVE,
+			wantHTTPMethod: http.MethodGet,
+			wantPath:       "/api/cve-id/CVE-2022-0000",
+			want:           defaultTestCVE,
+		},
+		{
+			name:       "ListOrgCVEs/single page",
+			query:      listOrgCVEsQuery,
+			mockStatus: http.StatusOK,
+			mockResponse: listOrgCVEsResponse{
+				CurrentPage: 0,
+				NextPage:    -1,
+				CVEs:        defaultTestCVEs,
+			},
+			wantHTTPMethod: http.MethodGet,
+			wantPath:       "/api/cve-id",
+			want:           defaultTestCVEs,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			validateRequest := func(t *testing.T, r *http.Request) {
+				if got, want := r.Method, test.wantHTTPMethod; got != want {
+					t.Errorf("incorrect HTTP method: got %v, want %v", got, want)
+				}
+				if got, want := r.URL.Path, test.wantPath; got != want {
+					t.Errorf("incorrect request URL path: got %v, want %v", got, want)
+				}
+			}
+			c, s := newTestClientAndServer(
+				newTestHandler(t, test.mockStatus, test.mockResponse, validateRequest))
+			defer s.Close()
+			got, err := test.query(c)
+			if err != nil {
+				t.Fatalf("unexpected error: %v", err)
+			}
+			if want := test.want; !reflect.DeepEqual(got, want) {
+				t.Errorf("got %v, want %v", got, want)
+			}
+		})
+	}
+}
+
+func TestAllFail(t *testing.T) {
+	tests := []struct {
+		name  string
+		query queryFunc
+	}{
+		{
+			name:  "ReserveIDs",
+			query: reserveIDsQuery,
+		},
+		{
+			name:  "RetrieveQuota",
+			query: retrieveQuotaQuery,
+		},
+		{
+			name:  "RetrieveCVE",
+			query: retrieveCVEQuery,
+		},
+		{
+			name:  "ListOrgCVEs",
+			query: listOrgCVEsQuery,
+		},
+	}
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+			mockStatus := http.StatusUnauthorized
+			mockResponse := apiError{
+				Error:   "more info",
+				Message: "even more info",
+			}
+			c, s := newTestClientAndServer(newTestHandler(t, mockStatus, mockResponse, nil))
+			defer s.Close()
+			want := "401 Unauthorized: more info: even more info"
+			_, err := test.query(c)
+			if err == nil {
+				t.Fatalf("unexpected success: want err %v", want)
+			}
+			if got := err.Error(); !strings.Contains(got, want) {
+				t.Errorf("unexpected error string: got %v, want %v", got, want)
+			}
+		})
+	}
+}
+
+func TestCreateListOrgCVEsRequest(t *testing.T) {
+	tests := []struct {
+		opts       ListOptions
+		page       int
+		wantParams string
+	}{
+		{
+			opts: ListOptions{
+				State:          cveschema.StateReserved,
+				Year:           2000,
+				ReservedBefore: &testTime2022,
+				ReservedAfter:  &testTime1999,
+				ModifiedBefore: &testTime2000,
+				ModifiedAfter:  &testTime1992,
+			},
+			page:       0,
+			wantParams: "cve_id_year=2000&state=RESERVED&time_modified.gt=1992-01-01T00%3A00%3A00Z&time_modified.lt=2000-01-01T00%3A00%3A00Z&time_reserved.gt=1999-01-01T00%3A00%3A00Z&time_reserved.lt=2022-01-01T00%3A00%3A00Z",
+		},
+		{
+			opts: ListOptions{
+				State:          cveschema.StateRejected,
+				Year:           1999,
+				ReservedBefore: &testTime1999,
+				ReservedAfter:  &testTime2000,
+				ModifiedBefore: &testTime1992,
+				ModifiedAfter:  &testTime2022,
+			},
+			page:       1,
+			wantParams: "cve_id_year=1999&page=1&state=REJECT&time_modified.gt=2022-01-01T00%3A00%3A00Z&time_modified.lt=1992-01-01T00%3A00%3A00Z&time_reserved.gt=2000-01-01T00%3A00%3A00Z&time_reserved.lt=1999-01-01T00%3A00%3A00Z",
+		},
+		{
+			opts: ListOptions{
+				State: cveschema.StatePublic,
+				Year:  2000,
+			},
+			page:       2,
+			wantParams: "cve_id_year=2000&page=2&state=PUBLIC",
+		},
+	}
+	for _, test := range tests {
+		t.Run(fmt.Sprintf("State=%s/Year=%d/ReservedBefore=%s/ReservedAfter=%s/ModifiedBefore=%s/ModifiedAfter=%s", test.opts.State, test.opts.Year, test.opts.ReservedBefore, test.opts.ReservedAfter, test.opts.ModifiedBefore, test.opts.ModifiedAfter), func(t *testing.T) {
+			c, s := newTestClientAndServer(nil)
+			defer s.Close()
+			req, err := c.createListOrgCVEsRequest(&test.opts, test.page)
+			if err != nil {
+				t.Fatalf("unexpected error creating ListOrgCVEs request: %v", err)
+			}
+			if got, want := req.URL.RawQuery, test.wantParams; got != want {
+				t.Errorf("incorrect request params: got %v, want %v", got, want)
+			}
+		})
+	}
+}
+
+func TestListOrgCVEsMultiPage(t *testing.T) {
+	extraCVE := newTestCVE("CVE-2000-1234", cveschema.StateReserved, "2000")
+	mockResponses := []any{
+		listOrgCVEsResponse{
+			CurrentPage: 0,
+			NextPage:    1,
+			CVEs:        defaultTestCVEs,
+		},
+		listOrgCVEsResponse{
+			CurrentPage: 1,
+			NextPage:    -1,
+			CVEs:        AssignedCVEList{extraCVE},
+		},
+	}
+
+	c, s := newTestClientAndServer(
+		newTestHandlerMultiPage(t, mockResponses, nil))
+	defer s.Close()
+	got, err := c.ListOrgCVEs(nil)
+	if err != nil {
+		t.Fatalf("unexpected error listing org cves: %v", err)
+	}
+	want := append(defaultTestCVEs, extraCVE)
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("got %v, want %v", got, want)
+	}
+}
