PHP
The PHP SDK for the Resend API, generated from the same spec as the other nine.
Get the source
gh repo clone OctriDev/resend-php-showcase-sdkThe repository's README lists the toolchain and build commands for PHP. Open it on GitHub.
Quickstart
<?php
require __DIR__ . '/vendor/autoload.php';
use octridev_resend\ClientConfig;
use octridev_resend\SdkConfig;
use octridev_resend\ClientAuthConfig;
use octridev_resend\Resend;
$config = new ClientConfig();
// Optional: replaces the default server and any server an operation declares.
$config->baseUrl = "https://api.resend.com";
$auth = new ClientAuthConfig();
$auth->bearerAuth = getenv('API_TOKEN') ?: throw new RuntimeException('API_TOKEN is required');
$config->auth = $auth;
$client = new Resend($config);
$result = $client->domains->get(domainId: "domain-1");
var_dump($result);Authentication
Keep credentials outside source control. The quickstart reads them from the environment and the client sends each one only on the operations whose security requirement accepts its scheme.
| Scheme | ClientAuthConfig field | Sent as |
|---|---|---|
| bearerAuth | bearerAuth | Authorization: Bearer … |
Client behavior
- Base URL:
https://api.resend.com. - Transport: cURL.
- Timeout: 30,000 ms per attempt.
- Retries: up to 3 attempts for status codes
408,425,429,500,502,503,504, with 500-8,000 ms backoff. - Idempotency: enabled for
POST,PATCHusingIdempotency-Key. - Error telemetry: off. This build has no reporting endpoint and sends no error reports.
High-level operation methods return the typed response body directly. The low-level request layer returns an SdkResponse<T> envelope containing data, status, headers, request ID, latency, and attempt count.
Errors
All failure paths use a small, predictable hierarchy:
| Error | Meaning |
|---|---|
SdkValidationError | A request argument failed an OpenAPI constraint before network I/O. |
SdkHttpError | The server returned a non-2xx response. |
SdkApiError | A 2xx response whose error envelope, when the API declares one, reports a failed call. It carries the envelope's error code. |
SdkResponseDecodeError | A 2xx response body or stream event did not decode into its declared type. It keeps the raw body. |
SdkNetworkError | DNS, connection, TLS, or socket failure. |
SdkTimeoutError | The configured per-attempt timeout elapsed. |
HTTP errors expose statusCode, the response body and headers, plus requestId when the server supplies one. Preserve the request ID in support logs; it is the fastest way to correlate a failed SDK call with server-side traces.
Common statuses are reported as a subclass of SdkHttpError, so a handler can catch only the one it handles: SdkBadRequestError (400), SdkUnauthorizedError (401), SdkPermissionDeniedError (403), SdkNotFoundError (404), SdkConflictError (409), SdkUnprocessableEntityError (422), SdkRateLimitError (429), SdkInternalServerError (any 5xx). Any other status is reported as SdkHttpError itself.
When the API declares a model for an error response, the SDK decodes the body into it as $error->data; narrow it with instanceof. It is empty when the status declares no model or the body does not fit one. The raw body stays on the error either way, and $error->decodeBody(ErrorModel::class) decodes it into any ErrorModel by hand.