Search by

easydown / api-client

mrzhangbo

PHP client for the EasyDown public-media API: normalized parsing, platform data and safe errors. Hosted API requires account, token and credits.

v0.1.0 2026-10-15 02:13 UTC

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.