Skip to main content
filecheck/filecheck-php mirrors the Node.js SDK method-for-method for PHP 8.1+. HTTP goes through any PSR-18 client (auto-discovered, or injected — Guzzle, Symfony HttpClient), with a bundled cURL fallback so it works with zero extra dependencies. Responses are typed, readonly value objects.
The secret key (sk_…) is server-side only. Load it from configuration or the environment — never commit it or expose it to the browser.

Verify a job before fulfilling

verify() confirms the job is terminal, proceedable (the Element’s canProceed equivalent, with the Workflow’s on-fail policy applied), and — with workflow_id — that it ran the expected Workflow. The returned VerifyResult carries ok, state, reason, and the full job.

Upload and process files

Every submit method takes 'wait' / 'wait_timeout' (seconds) instead of the API’s raw sync/async flags, with defaults matching each endpoint (validate and optimize wait by default; the rest are async). If the server’s ~27-second window elapses, the SDK keeps polling for you.
A blocking wait ties up the PHP worker — mind FPM request time limits. For long-running jobs, prefer the per-job webhook parameter and process the callback instead.

Surface

Client options: new FilecheckClient('sk_…', ['base_url', 'timeout', 'max_retries', 'http_client']). Passing a publishable pk_… key throws immediately, and keys are never echoed in full.

Webhooks

In Laravel, exempt the route from CSRF and use $request->getContent() for the raw body. Webhook signature verification is not yet live; ['verify' => false] is the explicit, temporary opt-in for unsigned payloads, and the helper is designed so verification becomes the default without a breaking change once the signing scheme ships.

Errors and retries

Typed exceptions in Filecheck\ExceptionAuthenticationException (401/403), InvalidRequestException (400), NotFoundException (404), RateLimitException (429), ApiException (5xx), ConnectionException — carry status and the parsed body. Catch by class, not message text. Idempotent GETs are retried automatically (exponential backoff with jitter, Retry-After honored). POSTs are never auto-retried: the API has no idempotency keys, and a duplicated POST /jobs creates and bills a second job.