Requirements
- PHP 8.2 or newer
Installation
composer require guzzlehttp/guzzle), or let Composer’s php-http/discovery plugin install
one when it asks.
Set up the client
Create an API key in Settings, then construct the client once and reuse it:https://promptjuggler.com. Pass baseUrl: to
target another deployment — the key goes to whatever URL you configure.
The client is found automatically. Pass your own as the second argument to set timeouts,
proxies, or middleware:
Per-endpoint usage
Every endpoint in the API reference includes a PHP SDK code sample showing the exact call — that’s the place to look for how to invoke each operation and what it returns. A typical flow:Methods return generated readonly objects (
PromptJuggler\Client\Models\…)
with public properties — read them, don’t set values back. A field the API
always sends is non-nullable; an optional one is null when absent. A
response that lacks a required field, or has one of the wrong type, throws a
DecodeException naming the field. Fields the SDK doesn’t know are ignored.Enums and unions
Enum properties are typed with their SDK cases plusUnknownEnumValue, for example
RunStatus|UnknownEnumValue. A value the API adds after your SDK version arrives as
UnknownEnumValue instead of failing the call. ->value works on both. A match without a
default arm throws UnhandledMatchError on such a value, and PHPStan flags it, so end it
with one:
Tool, ResponseFormat, and TranscriptItem are interfaces with one class per variant
(HttpCall, TranscriptText, …). Tell them apart with instanceof. A variant newer than
your SDK arrives as UnknownTool, UnknownResponseFormat, or UnknownTranscriptItem,
with its type and the raw object in data:
Error handling
When the API responds with an error status, the SDK throws aPromptJuggler\Client\Exception\ApiException carrying the HTTP status code (an int) and
the server’s message, or "{status} {reason}" when the body has none. When the request gets
no complete response (DNS failure, timeout, a dropped connection), it throws a
NetworkException. When the API replies with a success status but the SDK can’t decode the
body, it throws a DecodeException: the request succeeded, so retrying a run starts a second
one. All three live in PromptJuggler\Client\Exception and implement the
PromptJugglerException marker interface, so you can catch the whole surface at once.
InvalidArgumentException before anything is sent.
Webhooks
PromptJuggler signs every webhook with thePromptJuggler-Signature header. Verify
it against the raw request body, before any JSON decoding:
isValid recomputes the HMAC-SHA256 of {timestamp}.{raw_body}, compares it in
constant time, and rejects deliveries whose timestamp falls outside a tolerance
window (default 300s) to prevent replay. Widen or narrow it with the tolerance:
argument.