Retries and idempotency
The Poli Page .NET SDK retries transient failures automatically. Every POST request carries an auto-generated Idempotency-Key (a UUID v4), so retries do not produce duplicate stored documents on the server.
Default retry policy
Section titled “Default retry policy”- 5xx responses, 429 (rate limit), and
PoliPageNetworkException(network / timeout) are retried. - Up to
MaxRetriesattempts (default2— three total attempts). - Exponential backoff:
RetryDelay × 2^Nwith jitter in[0.5, 1.5), capped at 30 seconds. - Honours the
Retry-Afterresponse header when present. - 4xx (other than 429) and
OperationCanceledExceptionare never retried.
Disabling retries
Section titled “Disabling retries”Set MaxRetries = 0 to disable retries entirely:
var client = new PoliPageClient(new PoliPageClientOptions{ ApiKey = Environment.GetEnvironmentVariable("POLI_PAGE_API_KEY")!, MaxRetries = 0,});Idempotency
Section titled “Idempotency”Every POST request includes an Idempotency-Key header generated by the SDK. The API treats requests with the same key as the same operation, so retries from inside the SDK never create duplicate stored documents.
If you orchestrate your own retries on top of the SDK, supply a deterministic key via RequestOptions.IdempotencyKey:
byte[] pdf = await client.Render.PdfAsync( new ProjectModeInput { Project = "billing", Template = "invoice", Version = "1.0.0", Data = new Dictionary<string, object> { { "invoiceNumber", "INV-001" } }, }, new RequestOptions { IdempotencyKey = "invoice-INV-001-v1" });Same input + same key → same stored document. A different key with the same data → a new document.
Example
Section titled “Example”using PoliPage;
var client = new PoliPageClient(new PoliPageClientOptions{ ApiKey = Environment.GetEnvironmentVariable("POLI_PAGE_API_KEY")!, MaxRetries = 4, RetryDelay = TimeSpan.FromMilliseconds(250), OnRetry = evt => Console.WriteLine($"retry #{evt.Attempt} in {evt.Delay}: {evt.Reason}"),});
byte[] pdf = await client.Render.PdfAsync(new ProjectModeInput{ Project = "billing", Template = "invoice", Version = "1.0.0", Data = new Dictionary<string, object> { { "invoiceNumber", "INV-001" } },});