***

title: Use PHP SDKs generated in Postman
max-toc-depth: 2
topictype: reference
---------------------

For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://learning.postman.com/llms.txt. For full content including API reference and SDK examples, see https://learning.postman.com/llms-full.txt.

This guide provides instructions for using PHP SDKs generated by Postman SDK Generator. It covers how to import the SDK into your project, run example code, and best practices for using the SDK effectively in your applications.

## SDK structure

The PHP SDK includes the following key files:

* `src/Client.php` — The main SDK client, instantiated with named constructor arguments.
* `src/Services/` — Service classes with methods for each API endpoint.
* `src/Models/` — Data models (plain PHP classes with typed properties, enums, and `fromArray`/`jsonSerialize` support).
* `src/Exceptions/` — Exception classes (`ApiException` and typed error model exceptions).
* `src/Environment.php` — Environment constants with base URL values.
* `src/Retry.php` — Guzzle retry middleware.
* `composer.json` — Package manifest and autoloading configuration.

The following is an example of the typical structure of a generated PHP SDK:

<Folder name="your-sdk" defaultOpen>
  <File name="README.md" comment="SDK documentation and usage instructions" />

  <File name="composer.json" comment="Package manifest and autoloading configuration" />

  <File name=".gitignore" comment="Git ignore patterns for PHP projects" />

  <Folder name=".devcontainer" defaultOpen>
    <File name="devcontainer.json" comment="VS Code development container configuration" />
  </Folder>

  <Folder name="example" defaultOpen>
    <File name="index.php" comment="Runnable usage example" />
  </Folder>

  <Folder name="src" defaultOpen>
    <File name="Client.php" comment="Main SDK client" />

    <File name="Environment.php" comment="Base URL constants" />

    <File name="Retry.php" comment="Guzzle retry middleware" />

    <Folder name="Services" defaultOpen>
      <File name="BaseService.php" comment="HTTP layer (auth, retry, config)" />

      <File name="[ServiceName].php" comment="One file per API service group" />
    </Folder>

    <Folder name="Models" defaultOpen>
      <File name="[ModelName].php" comment="Request/response models and enums" />
    </Folder>

    <Folder name="Exceptions" defaultOpen>
      <File name="ApiException.php" comment="Base API exception class" />

      <File name="[ModelName]Exception.php" comment="Typed exceptions per error schema" />
    </Folder>

    <Folder name="OAuth" defaultOpen>
      <File name="OAuthToken.php" comment="OAuth token representation" />

      <File name="TokenManager.php" comment="Token lifecycle (fetch, cache, refresh)" />
    </Folder>

    <Folder name="Utils" defaultOpen>
      <File name="Serializer.php" comment="JSON serialization utilities" />

      <File name="LineDecoder.php" comment="Streaming / SSE support" />
    </Folder>
  </Folder>

  <Folder name="docs" defaultOpen>
    <Folder name="services" defaultOpen>
      <File name="[ServiceName].md" comment="Service-specific documentation" />
    </Folder>

    <Folder name="models" defaultOpen>
      <File name="[ModelName].md" comment="Model and type documentation" />
    </Folder>
  </Folder>
</Folder>

## Example usage

Each generated SDK includes an `example/` directory with a working script demonstrating SDK usage.

The example includes the following features:

* SDK initialization with named arguments
* Calling an API endpoint
* Constructing nested model inputs
* Exception handling

<Tabs>
  <Tab title="Location">
    `example/index.php`
  </Tab>

  <Tab title="Run the example">
    ```bash
    cd path/to/your-sdk
    composer install
    php example/index.php
    ```
  </Tab>

  <Tab title="Example code structure">
    ```php
    <?php

    require_once __DIR__ . '/../vendor/autoload.php';

    use YourSdk\Client;
    use YourSdk\Exceptions\ApiException;

    $sdk = new Client(accessToken: 'your-bearer-token');

    try {
        $user = $sdk->users->getUser('123');
        echo "User: " . $user->name . "\n";
    } catch (ApiException $e) {
        echo "Error: " . $e->getMessage() . "\n";
        echo "Status: " . $e->statusCode . "\n";
    }
    ```
  </Tab>
</Tabs>

## Import the PHP SDK locally

You can import the generated SDK using Composer from a local path or from [Packagist](https://packagist.org/). Below are instructions for each method.

### Import using a local path

To import an SDK that hasn't yet been published to Packagist, add a `path` repository to your project's `composer.json`:

```json
{
    "repositories": [
        {
            "type": "path",
            "url": "../path/to/your-sdk"
        }
    ],
    "require": {
        "your-vendor/your-sdk": "*"
    }
}
```

Then run:

```bash
composer install
```

### Import using Packagist

Once your SDK is published to [Packagist](https://packagist.org), add it as a standard dependency:

```bash
composer require your-vendor/your-sdk
```

Or add it manually to your `composer.json`:

```json
{
    "require": {
        "your-vendor/your-sdk": "^1.0"
    }
}
```

Then run `composer install`.

## Publish to Packagist

To share your generated PHP SDK with the community, you can publish it to [Packagist](https://packagist.org). This allows other developers to install it using `composer require`.

### Prerequisites

To publish your SDK to Packagist, you need the following:

* A public Git repository (for example, GitHub or GitLab).
* A [Packagist](https://packagist.org) account.
* A valid `composer.json` with a `name` field in `vendor/package` format.

### Initial setup

1. Push your SDK to a public repository.

2. Log in to [Packagist](https://packagist.org) and click **Submit**.

3. Enter your repository URL and submit. Packagist validates your `composer.json` and creates the package listing.

4. Configure a GitHub webhook so Packagist automatically picks up new versions. In your repository settings, follow the instructions shown on your Packagist package page under **Set up GitHub Hook**.

### Configure composer.json

Your SDK's `composer.json` should include the following fields for a proper Packagist listing:

```json
{
    "name": "your-vendor/your-sdk",
    "description": "SDK for Your API",
    "type": "library",
    "license": "MIT",
    "authors": [
        {
            "name": "Your Name",
            "email": "your@email.com"
        }
    ],
    "require": {
        "php": "^8.0",
        "guzzlehttp/guzzle": "^7.0",
        "symfony/serializer": "^7.0",
        "symfony/property-info": "^7.0",
        "symfony/property-access": "^7.0",
        "phpdocumentor/reflection-docblock": "^5.4"
    },
    "autoload": {
        "psr-4": {
            "YourSdk\\": "src/"
        }
    }
}
```

### Publish your PHP SDK to Packagist

To publish your SDK, do the following:

1. Tag a release using [semantic versioning](https://semver.org).

   ```bash
   git tag v1.0.0
   git push origin v1.0.0
   ```

2. Packagist picks up the tag automatically if the webhook is configured. Otherwise, trigger a manual update from your package page.

3. Verify the publication at `https://packagist.org/packages/your-vendor/your-sdk`.

### Publish updates

To publish updates to your SDK, do the following:

```bash
# Tag a new version
git tag v1.0.1
git push origin v1.0.1
```

### Best practices for publishing PHP SDKs

Use the following best practices when publishing your PHP SDK to Packagist:

* Use semantic versioning.
* Include a comprehensive `README.md` with installation and usage instructions.
* Tag releases in Git rather than relying on branch-based version constraints.
* Declare a specific PHP version constraint in `composer.json` (for example, `"php": "^8.1"`).
* Run your test suite before tagging a release.

## Advanced usage

You can further customize the SDK by modifying the generated code, adding new features, or integrating it with your existing codebase. Here are some advanced topics to explore.

### Authentication

The SDK supports various authentication methods. Configure authentication when instantiating the SDK client using named constructor arguments.

The SDK includes authentication support based on the security schemes defined in your API specification. The following examples show the possible authentication methods.

<Tabs>
  <Tab title="API Key">
    ```php
    use YourSdk\Client;

    $sdk = new Client(
        apiKey: 'your-api-key',
        apiKeyHeader: 'X-API-KEY',   // configurable; defaults to 'X-API-KEY'
    );
    ```
  </Tab>

  <Tab title="Bearer Token">
    ```php
    use YourSdk\Client;

    $sdk = new Client(
        accessToken: 'your-bearer-token',
    );
    ```
  </Tab>

  <Tab title="Basic Auth">
    ```php
    use YourSdk\Client;

    $sdk = new Client(
        username: 'your-username',
        password: 'your-password',
    );
    ```
  </Tab>

  <Tab title="OAuth 2.0">
    ```php
    use YourSdk\Client;

    $sdk = new Client(
        baseOAuthUrl:  'https://auth.example.com',
        clientId:      'your-client-id',
        clientSecret:  'your-client-secret',
    );

    // SDK automatically handles token acquisition and refresh
    $user = $sdk->users->getUser('123');
    ```
  </Tab>
</Tabs>

To update credentials after initialization, use the corresponding setter methods. The `setApiKey`, `setAccessToken`, `setBasicAuth`, `setClientId`, and `setClientSecret` methods are each only generated when the corresponding auth type is in the specification.

```php
$sdk->setApiKey('new-api-key');
$sdk->setAccessToken('new-token');
$sdk->setBasicAuth('new-username', 'new-password');
$sdk->setClientId('new-client-id');
$sdk->setClientSecret('new-client-secret');
```

### Error handling

The SDK raises `ApiException` for API errors, which includes details about the status code, response body, and headers. You can catch this exception to handle errors gracefully in your application.

To handle errors, do the following:

```php
use YourSdk\Exceptions\ApiException;

try {
    $user = $sdk->users->getUser('123');
    echo $user->name;
} catch (ApiException $e) {
    echo "Status: " . $e->statusCode . "\n";
    echo "Message: " . $e->getMessage() . "\n";
    echo "Body: " . $e->responseBody . "\n";
    print_r($e->responseHeaders);

    // Attempt to decode the response body as JSON
    $decoded = $e->getDecodedBody(); // returns array|null
}
```

To handle specific status codes, do the following:

```php
try {
    $sdk->users->deleteUser('123');
} catch (ApiException $e) {
    match ($e->statusCode) {
        404     => print("User not found\n"),
        403     => print("Permission denied\n"),
        default => print("API error: " . $e->getMessage() . "\n"),
    };
}
```

When the API specification defines error response models, the SDK generates typed exception classes (for example, `ValidationErrorException`) that extend `ApiException` and include the deserialized error model. Access the model using `getError()`.

```php
use YourSdk\Exceptions\ApiException;
use YourSdk\Exceptions\ValidationErrorException;

try {
    $sdk->users->createUser($newUser);
} catch (ValidationErrorException $e) {
    $error = $e->getError(); // Returns a typed ValidationError model instance
    echo "Validation message: " . $error->message . "\n";
    echo "Field: " . $error->field . "\n";
} catch (ApiException $e) {
    // Fallback for all other HTTP errors
    echo "API error: " . $e->statusCode . "\n";
}
```

### Environment management

The SDK supports multiple environments (for example, production, staging) with different base URLs.

```php
use YourSdk\Client;
use YourSdk\Environment;

// Use an environment constant defined in the spec
$sdk = new Client(
    accessToken: 'your-token',
    environment: Environment::Production,
);

// Or set a fully custom base URL at any time
$sdk->setBaseUrl('https://staging.api.example.com');
```

Available environment constants are defined in `src/Environment.php`.

### Hierarchical configuration

PHP supports four levels of configuration: SDK (through the constructor or `setBaseUrl()`), service, method, and request. Each level overrides the previous, with request being most specific.

```php
use YourSdk\Client;
use YourSdk\Environment;

// 1. SDK level — default for everything
$sdk = new Client(
    accessToken: 'your-token',
    timeout: 10000,
    environment: Environment::Default,
);

// 2. Service level — override for all methods in usersService
$sdk->users->setConfig([
    'timeout'     => 15000,
    'accessToken' => 'service-scoped-token',
]);

// 3. Method level — override for getUser only
$sdk->users->setGetUserConfig([
    'baseUrl' => 'https://legacy-api.example.com',
    'timeout' => 20000,
]);

// 4. Request level — override for this single call
$user = $sdk->users->getUser('123', requestConfig: [
    'timeout'     => 30000,
    'accessToken' => 'request-scoped-token',
]);
```

Supported configuration keys depend on the auth type defined in the specification:

| Key                     | Type   | Description                       |
| ----------------------- | ------ | --------------------------------- |
| `baseUrl`               | string | Override base URL.                |
| `timeout`               | float  | Request timeout, in milliseconds. |
| `accessToken`           | string | Bearer token override.            |
| `apiKey`                | string | API key override.                 |
| `username` / `password` | string | Basic auth override.              |
| `retryConfig`           | array  | Retry settings override.          |

### Timeouts and retries

To set a global timeout, do the following:

```php
$sdk = new Client(
    accessToken: 'your-token',
    timeout: 10000, // 10 seconds in milliseconds (default: 10000)
);
```

To configure retries, pass a `retryConfig` array to the constructor:

```php
$sdk = new Client(
    accessToken: 'your-token',
    retryConfig: [
        'isEnabled'         => true,
        'maxRetries'        => 3,
        'baseDelayMs'       => 150,    // initial delay in milliseconds (default: 150)
        'maxDelayMs'        => 5000,   // max delay cap in milliseconds (default: 5000)
        'delayJitter'       => 50,     // random jitter in milliseconds (default: 50)
        'delayMultiplier'   => 2.0,    // exponential backoff multiplier (default: 2.0)
        'retryableStatuses' => [408, 429, 500, 502, 503, 504],
        'retryableMethods'  => ['GET', 'PUT'],
    ],
);
```

To turn off retries entirely:

```php
$sdk = new Client(
    accessToken: 'your-token',
    retryConfig: ['isEnabled' => false],
);
```

### Optional and nullable field handling

The SDK uses PHP's native nullable type syntax (`?Type`) to represent optional and nullable fields. Optional fields default to `null` in model constructors.

```php
use YourSdk\Models\Pet;

// Required fields must be provided; optional fields default to null
$pet = new Pet(
    id:   123,
    name: 'Fido',
    tag:  'dog',   // optional field — omit to leave as null
);

// Optional fields omitted entirely
$minimalPet = new Pet(
    id:   456,
    name: 'Whiskers',
    // tag is null — omitted from the JSON payload sent to the API
);
```

PHP 8.1 native backed enums are used for fields with a fixed set of allowed values:

```php
use YourSdk\Models\StatusEnum;

// Create using the enum case
$pet = new Pet(id: 1, name: 'Rex', status: StatusEnum::Available);

// Enums are deserialized automatically from API responses
$pet = $sdk->pets->getPetById(1);
echo $pet->status->value; // "available"
```

## Additional resources

Consider the following resources for using and customizing your PHP SDK:

* SDK documentation — Check the `docs/` directory in your SDK for per-service and per-model reference pages.
* Example usage — Refer to the `example/` directory for a working script demonstrating basic SDK usage.
* Dependencies — The SDK uses the following dependencies:
  * [GuzzleHTTP](https://docs.guzzlephp.org) — HTTP client and middleware.
  * [Symfony Serializer](https://symfony.com/doc/current/components/serializer.html) — JSON serialization.
  * [Symfony PropertyInfo](https://symfony.com/doc/current/components/property_info.html) and [PropertyAccess](https://symfony.com/doc/current/components/property_access.html) — Model introspection.
  * [PHPDocumentor Reflection Docblock](https://github.com/phpDocumentor/ReflectionDocBlock) — Type resolution for deserialization.