Docs/Platform/SDKs and libraries

SDKs and libraries

One generated package per API in seven ecosystems, plus a CLI — what exists, what it is called, what it does for you, and when calling the endpoint directly is the better choice.

Every API is published as its own package rather than one omnibus client. Installing the email validator gets you the email validator and nothing else — no catalog-sized dependency, and a version number that only moves when that API changes.

That is an unusual choice, so it is worth saying why. An omnibus client for a catalog this size means every consumer takes a dependency on code for hundreds of endpoints they will never call, and a patch to any one of them bumps everybody's lockfile. Per-API packages keep the blast radius of a change to the people actually affected by it.

Where the packages are

EcosystemPackage nameCoverage
npm@apiverve/<api-id>357
NuGetAPIVerve.API.<ApiName>357
PyPIapiverve-<api-name>356
Gogithub.com/apiverve/<api-id>-api/go356
Android / Javacom.github.apiverve:<api-id>-api (JitPack)356
Packagistapiverve/<api-id>180
pub.devapiverve_<api-id>156

The <api-id> is the same identifier as the URL of the reference page: /ref/emailvalidator is @apiverve/emailvalidator. Packages are generated from the published schema, so a new API appears in every full-coverage ecosystem on the next build; PHP and Dart lag the catalog and are filled in by demand rather than automatically.

If a package is missing for your language, nothing is lost — the endpoint is an ordinary HTTPS GET or POST and the SDK is a convenience, not a requirement. Skip to calling without an SDK.

Installing

bash
npm install @apiverve/emailvalidator
pip install apiverve-emailvalidator
dotnet add package APIVerve.API.EmailValidator
composer require apiverve/emailvalidator
go get github.com/apiverve/emailvalidator-api/go

Every package is versioned independently and follows semver. A minor bump means new optional parameters or new response fields; the request and response shapes you already depend on do not change under you.

Calling

Every package has the same two-step shape: construct with a key, call execute with the same parameters the reference page documents. Once you have used one, you have used all of them.

const EmailValidator = require('@apiverve/emailvalidator');

const api = new EmailValidator({ api_key: process.env.APIVERVE_API_KEY });

const result = await api.execute({ email: 'hi@example.com' });
console.log(result.data);

Two details that catch people out:

  • The Node constructor key is api_key, not apiKey. A wrong key name means the client constructs with no credential and throws before it ever makes a request.
  • execute returns a promise in Node and also accepts a Node-style callback as a second argument. With a callback, errors are delivered to the callback and not thrown.

The secure constructor option still exists in older releases and is deprecated — every request goes over HTTPS regardless, and passing false does nothing.

Endpoints that take a file

APIs that accept an upload have two extra entry points rather than putting the file in the query string:

js
await api.executeWithFile('/path/to/photo.png', { fields: { format: 'jpg' } });
await api.executeWithUrl('https://example.com/photo.png', { fields: { format: 'jpg' } });

executeWithUrl fetches the file server-side, which is usually the better option when the source is already on the public internet — it saves you the round trip of downloading and re-uploading.

What the packages actually do for you

They are generated from the same schema that produces the reference pages, so:

  • Parameters are validated before the request leaves your process. Required fields, types, numeric ranges and string lengths are checked client-side. A typo fails immediately with a message naming the parameter, instead of costing a round trip and a credit.
  • The host, path and version are baked in. There is no base URL to configure and nothing to update when the API version moves.
  • Authentication is one constructor argument. The header name, casing and format are handled for you — which removes the single most common cause of a mystifying 403.
  • Types ship with the packageindex.d.ts for TypeScript, type hints for Python, real types for C#, Go and Java. Response fields autocomplete instead of being guessed.
  • Requests identify themselves. Each package sends an auth-mode header naming the ecosystem, which is how support can tell an SDK call from a hand-rolled one when tracing an issue.

What they do not do

There is no built-in retry

No package implements backoff. A 429 or a 5xx comes back to you as-is, and retrying is your code's job. See rate limits for the backoff shape to use, and keep the jitter — a fleet of clients retrying on the same schedule rebuilds the spike that caused the 429.

The client-side validator checks what the schema declares. It cannot know whether a well-formed value is correct, so a syntactically valid but wrong parameter still reaches the API and still costs a credit.

Error handling

This is the one place where the SDKs behave differently from what most clients expect, and it is worth reading before you write your first catch.

On a failed request the Node package throws the API's response body, not an Error object:

js
try {
  const result = await api.execute({ email: 'not-an-email' });
} catch (err) {
  // err is { status: 'error', error: 'The ...', data: null }
  console.error(err.error);       // the message
  console.error(err.message);     // undefined — this is not an Error
}

So read err.error, not err.message. The thrown object also carries no HTTP status code, which means the status-based retry logic has to key off the message, or the call has to be made over plain HTTP where the status is visible. If you need statuses, that is a good reason to skip the SDK for that path.

Validation failures raised before the request are a different thing again: those are real Error objects with a message naming the offending parameter, and they never reach the network.

The CLI

For scripts, shell pipelines and one-off checks, the command-line client covers the whole catalog without installing anything per API:

bash
npm install -g @apiverve/cli

apiverve emailvalidator --email hi@example.com
apiverve weather --city London --format json | jq '.data.current'

It reads APIVERVE_API_KEY from the environment, so there is no key to pass on every invocation and none ends up in your shell history. Output is the raw envelope, which pipes cleanly into jq.

There is also a Docker image if you would rather not install Node:

bash
docker run --rm -e APIVERVE_API_KEY apiverve/cli emailvalidator --email hi@example.com

Calling without an SDK

These are ordinary REST endpoints. A single call is one fetch, and pulling in a package to make it is often the more complicated option:

bash
curl 'https://api.apiverve.com/v1/emailvalidator?email=hi@example.com' \
  -H "x-api-key: $APIVERVE_API_KEY"

Reach for a package when you are calling one API repeatedly and want the parameter validation and the types. Call the endpoint directly when:

  • you need the HTTP status code — for retry logic, or for telling a 429 for rate from a 429 for credits;
  • you are in a language with no package;
  • you are writing a script, where one curl beats an install;
  • you are in a browser — see CORS, and note that shipping a key to a client is a key-scoping problem before it is an SDK one.

Making requests has the same call written out in four languages, plus the timeout, concurrency and caching guidance that applies either way.

Getting help

Each package's README carries its own usage examples, generated from the same schema as its reference page. Bugs and feature requests belong on the package's GitHub repository, which is linked from the package listing in every registry. For anything about the API behind the package rather than the package itself, the reference page is the authority — the SDK is a thin wrapper and almost every surprising response is the API's behaviour, not the wrapper's.

Next

Parameters and responses for a specific API are on its reference page in all endpoints. For agents rather than applications, the MCP server exposes the same catalog as native tools, and GraphQL exposes it as a single typed query surface.

To try a call before you install anything, the playground runs it in the browser and Studio runs it on the desktop. Swapping an SDK in for an existing client is covered in migrations.

Was this page helpful?

Last updated