Search the docs
Find a page, a section, or an endpoint.
SDKs
The TypeScript and Python clients, generated from one document.
Two clients, TypeScript and Python, both generated from
openapi.json — which is itself generated
from the schemas the API validates with. An operation has the same name in
both, because both take it from the same field.
npm install @pidgeon-ai/sdkConfigure once
import { client } from '@pidgeon-ai/sdk';
client.setConfig({ auth: () => process.env.PIDGEON_API_KEY! });TypeScript has a module-level client the functions use when you do not pass one; Python threads it through each call. That difference is each language's idiom rather than a disagreement about the API.
Call an operation
import { messagesSend } from '@pidgeon-ai/sdk';
const { data, error } = await messagesSend({
body: {
from: 'you@yourdomain.com',
to: 'someone@example.com',
subject: 'First one',
text: 'It works.',
},
});messagesSend and messages_send are the same operation. Every one is named
this way, so a method you find in one language tells you what to look for in
the other.
Errors
TypeScript answers, it does not throw. A call returns { data, error, response }, and error carries the API's own code and message. Pass
throwOnError: true on a call that should raise instead.
const { data, error } = await identitiesGet({ path: { id } });
if (error) {
console.error(error.error.code, error.error.message);
}Python raises on an unexpected status and otherwise returns the parsed body,
or None where the response has no JSON to parse.
Verifying a webhook
The one thing in the TypeScript package that is written rather than generated, because HMAC is a security contract and not an endpoint:
import { verifyWebhook } from '@pidgeon-ai/sdk';
const event = await verifyWebhook({
rawBody: await request.text(),
headers: request.headers,
secret: process.env.PIDGEON_WEBHOOK_SECRET!,
});Verifying a signature has the whole of it, including what to do in Python, where the package does not ship a verifier.
What message/rfc822 does in Python
GET /messages/{id}/raw returns the original message rather than JSON, and
the Python generator will not parse a non-JSON body. The call works: the
bytes are on .content, and .parsed is None.