All notable changes to the Rust Apify API client are documented here. The format is based on Keep a Changelog and the project adheres to Semantic Versioning.
Compliance fix for the updated client/test requirements (apify-client-orchestration PR #4). No changes to the public interface; CI and documentation-testing only.
- CI: added a standalone
Test examplesworkflow step that verifies the documentation examples actually work — it runs theexamples/programs end-to-end against the live API (theexample_*smoke tests intests/examples.rs, each invokingcargo run --example) and runs the in-documentation code snippets as doctests (cargo test --doc). The example smoke tests were previously executed as part of theRun integration testsstep and the doctests in a separateRun documentation example testsstep; they are now consolidated under the requirement-namedTest examplesstep.Run integration testsnow skips theexample_*tests (via--skip example_) so the two concerns stay separate. - Documentation testing: the external
docs/pages (docs/README.md,docs/actors.md,docs/misc.md,docs/storages.md,docs/runs.md,docs/builds.md) are now compiled as doctests via#[doc = include_str!]insrc/lib.rs, so every in-documentationrustcode snippet is verified valid and runnable bycargo test --doc. Previously only the rootREADME.mdsnippets were doctest-checked. - Documentation: added response-model field tables for the types the README Quick start and the
examples read but which were previously undocumented —
ActorRun(incl.id,status,default_dataset_id/default_key_value_store_id/default_request_queue_id) indocs/runs.md;Actor(id, …) andBuild(id,status, …) indocs/actors.md(with a cross-reference fromdocs/builds.md); the shared storage-metadata fields ofDataset/KeyValueStore/RequestQueue(incl.id) indocs/storages.md; andUser(id,username) indocs/misc.md. Each new section carries a runnableno_rundoctest exercising the documented fields.
Updated to Apify OpenAPI specification v2-2026-06-18T095846Z (previously
v2-2026-06-16T064758Z). The spec delta is small and fully additive; no breaking changes to
the public interface.
ActorClient::validate_input_for_build— validates input against the input schema of a specific Actor build, exposing the spec's optionalbuildquery parameter onPOST /v2/actors/{actorId}/validate-input. The existingvalidate_inputis unchanged and now delegates to it withNone(default build).UserClient::monthly_usage_for_date— fetches monthly usage for the month containing a givenYYYY-MM-DDdate, exposing the spec's optionaldatequery parameter onGET /v2/users/me/usage/monthly. The existingmonthly_usageis unchanged and now delegates to it withNone(current month).- Integration tests:
get_monthly_usage_for_date(user) and avalidate_input_for_buildcall added tobuild_actor_flow(where a reallatestbuild exists to validate against).
API_SPEC_VERSIONbumped tov2-2026-06-18T095846Z.
ActorClient::validate_input(and the newvalidate_input_for_build) no longer fail to parse the response. Thevalidate-inputendpoint returns a bare{ "valid": ... }object rather than the usual{ "data": ... }envelope, so it now skipsdata-envelope unwrapping (new internalpost_action_rawhelper). Previously any call returned a deserialization error (missing field 'data'). Exercised by thevalidate_input_for_buildassertion in thebuild_actor_flowintegration test.UserClient::monthly_usage'sme-only guard error now namesmonthly_usageinstead of the delegatedmonthly_usage_for_date, so a non-mecaller sees the method they actually called.
Initial release of the official Rust client for the Apify API.
- Resource-oriented async client (
ApifyClient+ApifyClientBuilder) mirroring the official JavaScript and Python clients. - Resource clients for Actors, Actor builds, Actor runs, Actor tasks, datasets, key-value stores, request queues, schedules, webhooks, webhook dispatches, the Apify Store, users, Actor versions and environment variables, and logs.
- Convenience helpers:
actor.call/task.call(start + wait + run),run.wait_for_finishandbuild.wait_for_finish, dataset push/list items, key-value store records, request queue operations, log retrieval and streaming (log redirection), and lazy iteration of Apify Store Actors (store().iterate()). - Replaceable HTTP transport via the
HttpBackendtrait with a default reqwest backend. - Automatic Bearer authentication, the mandated
User-Agentheader, and transparent retries with exponential backoff on429/5xx/network errors. - Public version constants
CLIENT_VERSIONandAPI_SPEC_VERSION(v2-2026-06-16T064758Z). - Request-queue lock lifecycle:
list_requests,list_and_lock_head,prolong_request_lock,delete_request_lock,unlock_requests, plusbatch_add_requests/batch_delete_requests. - Dataset
download_items(JSON/CSV/XLSX/XML/RSS/HTML export) andget_statistics. KeyValueStoreClient::get_records— downloads all records from a store as a ZIP archive (GET /v2/key-value-stores/{storeId}/records), withcollection/prefix/signaturefiltering viaGetRecordsOptions. Reachable on run/task default stores via the nestedkey_value_store()accessor.- Build
get_openapi_definition. ApifyClient::set_status_messagefor setting the current run's status from inside an Actor.- Public, shareable resource URLs with HMAC-SHA256 signing for private resources:
DatasetClient::create_items_public_url,KeyValueStoreClient::get_record_public_url/create_keys_public_url, plus a configurablepublic_base_url. - Format-specific dataset export options via
DatasetDownloadOptions(attachment,bom,delimiter,skip_header_row,xml_root,xml_row). - Full parameter coverage on list/start endpoints (
my/sortByfor Actors;webhooks,restartOnError,forcePermissionLevelfor run start;unwind/flatten/view/etc. for dataset items;includeUnrunnableActorsfor store;attachmentfor KVS records). - Offline unit tests (mock
HttpBackend) covering retry counting, 429/5xx retry vs. 4xx no-retry, network-error retry, backoff, error-envelope parsing and 404→None mapping. - Integration test suite covering simple GETs and full CRUD flows for each resource.
- GitHub Actions workflow running formatting, clippy, build and integration tests.
- Percent-encode URL path segments (key-value-store record keys, request-queue request IDs)
so keys containing
/,?,#, spaces or non-ASCII no longer produce malformed URLs. User-AgentisAtHomeflag now reads both the platform variableAPIFY_IS_AT_HOME(matching the JS reference) and the bareisAtHomename fromclient_requirements.md; either being set marks the client "at home". These two same-priority requirements conflicted, so the client honours both (consistent with the Go sibling). The flag is rendered lowercase (true/false) to stay byte-consistent with the JS reference.get_recordnow sendsattachment=true, matching the reference client'sgetRecord(which sendsattachment=trueunconditionally).get_record_with_optionstakes aGetRecordOptions { attachment, signature };attachmentdefaults totruewhen unset.- Request-queue request pagination (
paginate_requests/RequestQueueRequestsIterator) now feeds the opaquenextCursorback as thecursorquery parameter on subsequent pages (matching the JS reference) instead of misusing it asexclusiveStartId. Previously pagination broke past the first page (duplicate/missing items or premature stop). User-Agent{language version}now reports the real compiler version captured at build time (viabuild.rsrunningrustc --version) instead of renderingRust/unknown(it previously read the unset MSRV fieldCARGO_PKG_RUST_VERSION).
- Added previously-missing spec query parameters: dataset items
outputFields(list/download) andfeedTitle/feedDescription(download); key-value-store keyscollection/signature; key-value-store recordsignature(viaGetRecordOptions); request-queue requestscursor/filter(viaListRequestsOptions); storage collection listunnamed/ownership(viaStorageListOptions); run collection liststartedAfter/startedBefore(viaRunListOptions). - Added the
signaturequery parameter to dataset items (DatasetListItemsOptions, inherited byDatasetDownloadOptions), solist_items/download_itemscan fetch items from a private dataset using a pre-shared signature (spec + JS reference both expose it). get_record_with_optionssignature changed to takeGetRecordOptions(wasattachment: bool), exposing the specsignatureparam for reading records from private stores.ActorClient::default_buildnow takes await_for_finish: Option<i64>argument (matching the reference client'sdefaultBuild(options)), optionally bounding how long the API waits for the default build to finish.- Backoff doubling factor extracted to a named constant.
- Cross-client consistency with the JS reference and the OpenAPI spec (aligning with the Go
sibling):
RunClient::chargenow takesRunChargeOptions { event_name, count, idempotency_key }and always sends anidempotency-keyheader (auto-generated as{runId}-{eventName}-{millis}-{random}when omitted), so a transport-retried charge is applied at most once. (Wascharge(event_name, count)with no idempotency key.)RunClient::metamorphnow takesRunMetamorphOptions { build, content_type }, letting the caller set the input body content type (defaults toapplication/json). (Wasmetamorph(target, input, build).)RunResurrectOptionsgainedmax_items,max_total_charge_usd, andrestart_on_error(all declared byPOST /v2/actor-runs/{runId}/resurrectand supported by the JS reference).RunListOptions::statusis nowVec<String>(sent comma-separated), so multiple run statuses can be filtered in one call, matching the spec's arraystatusparameter. (Was a singleOption<String>.)RunClient::abortnow takesgracefully: Option<bool>instead ofbool. PassingNoneomits thegracefullyquery parameter (letting the server apply its default, immediate abort), matching the reference client's optionalgracefullyoption and the Go sibling.RequestQueueClient::batch_add_requestsnow splits inputs larger than the API's 25-per-call limit into chunks and merges the per-chunkprocessedRequests/unprocessedRequestsresults, matching the reference client's client-side chunking. (Was a single raw POST of the whole slice, which could exceed API limits for large batches.)
- A few documented endpoints are intentionally not exposed (matching the JS reference):
synchronous run endpoints,
/tools/*,/browser-info, and the keyed-POSTcreate variants for Actor versions and version env-vars (creation is viaPOSTto the collection, upsert viaPUTon the keyed path). - The JS
listItemschunkSizeoption is intentionally not exposed: it is a client-side hint controlling the per-request page size of the JS async-iterator, not an API query parameter. The Rustlist_itemsreturns a singlePaginationListpage (the caller controls the page size vialimit), sochunkSizehas no analogue here. - The
POSTstore-record aliasPOST /v2/key-value-stores/{storeId}/records/{recordKey}is intentionally not exposed: the spec defines it as behaving identically to the coveredPUTvariant, and the reference client stores records viaPUTonly. Records are stored withset_record_raw/set_record_json.