easydown / api-client
PHP client for the EasyDown public-media API: normalized parsing, platform data and safe errors. Hosted API requires account, token and credits.
Requires
- php: >=8.3
- ext-curl: *
- ext-json: *
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-10-16 00:47:50 UTC
README
For a PHP backend that accepts one public post URL, this client keeps the two EasyDown response contracts separate: normalized media for a shared import pipeline, or normalized media plus platform-specific fields when you need them. It submits parsing requests; it does not fetch media files or crawl profiles.
Maintained for EasyDown. This PHP library is open source under ISC, while the hosted Video Downloader API is a paid, credit-based service. You need an account, a Bearer token and available credits; new registrations receive 10 trial credits. The free browser downloader is a separate product. Parse costs depend on the platform and processing outcome, so a failed response or timeout does not by itself prove that no credits were charged.
See the EasyDown API reference for supported URL formats, authentication, current billing rules and platform contracts.
Installation
Requires PHP 8.3 or newer with the cURL and JSON extensions.
composer require easydown/api-client
Import normalized media
Keep your token on the server in EASYDOWN_API_TOKEN, and set PUBLIC_POST_URL
to a supported public single-post URL that you are authorized to process.
<?php require __DIR__ . '/vendor/autoload.php'; use EasyDown\ApiClient\Client; use EasyDown\ApiClient\ApiException; $client = new Client(getenv('EASYDOWN_API_TOKEN') ?: ''); try { $media = $client->parse(getenv('PUBLIC_POST_URL') ?: ''); echo $media['platform'] . ': ' . count($media['images']) . " images\n"; } catch (ApiException $error) { // Log classifications, not tokens, submitted URLs or response bodies. error_log($error->kind . ' HTTP=' . ($error->httpStatus ?? 0)); }
parse() sends POST /api/v1/parse with a JSON url field. The return value
is the normalized media object from data, without a platformData wrapper.
Images stay in response order; video variants are not separate posts or billing
units. duration is passed through without inventing a unit.
Read platform-specific fields
$result = $client->parsePlatform('tiktok', getenv('PUBLIC_POST_URL') ?: ''); $media = $result['media']; $platformData = $result['platformData']; $contractVersion = $result['platformDataVersion'];
This uses POST /api/v1/platforms/tiktok/parse. The client validates the media
platform, preserves additional returned fields and keeps the three data members
separate. Check the contract version and optional fields before reading nested
platform values. JSON objects decode to associative PHP arrays; empty objects
therefore appear as empty arrays.
Endpoint names: tiktok, douyin, toutiao, youtube, twitter, instagram,
threads, xiaohongshu, bilibili, kuaishou, weibo. X uses twitter and
RedNote uses xiaohongshu. This does not guarantee every post is available;
private content, profile crawling and live streams are outside this example.
Failure behavior
http: redirects and unsuccessful HTTP statuses, including 401, 402 and 429.api: an API error envelope despite successful HTTP transport.invalid_response: malformed JSON, missing media fields or a response above 8 MiB.timeout/network: transport failure; processing and billing may be unknown.
Recognized API error codes are exposed as ApiException::$apiCode. Upstream
messages and raw bodies are omitted. The default cURL transport uses a fixed
HTTPS API host, verifies certificates and refuses redirects. It uses a 60-second
total transfer timeout and a connection timeout of at most 10 seconds, with no
automatic retries. Applications must choose their own retry and credit policy.
Do not serialize clients or log request arguments. Enable PHP's
zend.exception_ignore_args=1 in production; sensitive request parameters also
use SensitiveParameter. Returned media URLs and media headers may be
short-lived or sensitive. The client never follows them automatically.
Development checks
composer validate --strict
composer install
composer test
Tests use synthetic responses and namespace-local cURL doubles, including the
default transport's TLS, redirect, timeout and streaming-limit configuration.
They make no network request, use no real token and spend no API credits. A
trusted optional Closure transport can be passed as the third constructor
argument; it receives (url, headers, jsonBody, timeoutMilliseconds) and must
return [integerHttpStatus, stringResponseBody]. It receives the Bearer token,
so only supply code you trust. Offline tests do not establish live API uptime.
Initial version 0.1.0. Code and documentation were prepared with AI assistance and checked against the published API contract.