Experimental — AI-generated and AI-maintained. This client is experimental. It is generated and maintained by AI, and is not (yet) an officially supported Apify product. Review the code before relying on it in production and report issues on the repository.
An idiomatic Go client for the Apify API.
It provides a resource-oriented interface that mirrors the official
JavaScript and Rust clients: start from an
ApifyClient, then drill down into resources (Actors, runs, datasets, key-value stores,
request queues, tasks, schedules, webhooks, the store, users and logs).
- Resource-oriented API surface consistent with the reference clients.
- Transparent authentication,
User-Agentheader, retries with exponential backoff, and per-request timeouts applied to every call. - Replaceable HTTP transport (the
HTTPBackendinterface) with a default implementation. - Convenience helpers: start-and-wait, build/run polling, lazy store and request-queue iterators, dataset export, signed public URLs, request-queue locking, and more.
- Forward-compatible models that keep unknown API fields in an
Extramap. - Zero third-party dependencies (standard library only).
go get github.com/apify/apify-client-goRequires Go 1.23 or newer.
package main
import (
"context"
"fmt"
"log"
apify "github.com/apify/apify-client-go"
)
func main() {
client := apify.NewClient("my-api-token")
ctx := context.Background()
// Start an Actor and wait for it to finish.
waitSecs := int64(120)
run, err := client.Actor("apify/hello-world").Call(ctx, nil, apify.ActorStartOptions{}, &waitSecs)
if err != nil {
log.Fatal(err)
}
// Read items from the run's default dataset.
page, err := client.Dataset(run.DefaultDatasetID).ListItems(ctx, apify.DatasetListItemsOptions{})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Got %d items\n", page.Count)
}Use NewClient(token) for a token-only setup, or NewClientWithOptions with functional
options for full control:
client := apify.NewClientWithOptions(
apify.WithToken("my-api-token"),
apify.WithBaseURL("https://api.apify.com"), // /v2 is appended automatically
apify.WithMaxRetries(8), // default 8
apify.WithMinDelayBetweenRetries(500*time.Millisecond),
apify.WithTimeout(360*time.Second), // default 6 minutes
apify.WithUserAgentSuffix("MyTool/1.0"),
apify.WithHTTPBackend(apify.NewDefaultHTTPBackend()),
)| Option | Default | Description |
|---|---|---|
WithToken |
— | API token, sent as a Bearer token. |
WithBaseURL |
https://api.apify.com |
API base URL; /v2 is appended automatically. |
WithPublicBaseURL |
API base URL | Base URL used for building public, shareable URLs. |
WithMaxRetries |
8 |
Maximum retries for failed requests. |
WithMinDelayBetweenRetries |
500ms |
Minimum delay between retries (doubled each retry). |
WithTimeout |
360s |
Overall per-request timeout. |
WithUserAgentSuffix |
— | Suffix appended to the User-Agent header. |
WithHTTPBackend |
DefaultHTTPBackend |
Replaceable HTTP transport. |
The User-Agent header reports an isAtHome flag indicating whether the client runs on the
Apify platform. It is driven by an environment variable: the client reads both
APIFY_IS_AT_HOME (used by the JavaScript reference client) and the bare isAtHome name; if
either is set to a non-empty value, the flag is true.
| Accessor | Returns | Purpose |
|---|---|---|
client.Actors() / client.Actor(id) |
*ActorCollectionClient / *ActorClient |
List/create Actors; manage a single Actor and its runs, builds, versions, webhooks. |
client.Builds() / client.Build(id) |
*BuildCollectionClient / *BuildClient |
List builds; inspect, abort, wait for, and read a build's log/OpenAPI. |
client.Runs() / client.Run(id) |
*RunCollectionClient / *RunClient |
List runs; manage a run, its default storages, and its log. |
client.Datasets() / client.Dataset(id) |
*DatasetCollectionClient / *DatasetClient |
List/get-or-create datasets; read/write/export items. |
client.KeyValueStores() / client.KeyValueStore(id) |
*KeyValueStoreCollectionClient / *KeyValueStoreClient |
List/get-or-create stores; read/write records and keys. |
client.RequestQueues() / client.RequestQueue(id) |
*RequestQueueCollectionClient / *RequestQueueClient |
List/get-or-create queues; add/list/lock requests. |
client.Tasks() / client.Task(id) |
*TaskCollectionClient / *TaskClient |
List/create tasks; manage a task, its input and runs. |
client.Schedules() / client.Schedule(id) |
*ScheduleCollectionClient / *ScheduleClient |
List/create schedules; manage a single schedule. |
client.Webhooks() / client.Webhook(id) |
*WebhookCollectionClient / *WebhookClient |
List/create webhooks; manage and test a single webhook. |
client.WebhookDispatches() / client.WebhookDispatch(id) |
*WebhookDispatchCollectionClient / *WebhookDispatchClient |
List/inspect webhook dispatches. |
client.Store() |
*StoreCollectionClient |
Browse and iterate the Apify Store. |
client.Me() / client.User(id) |
*UserClient |
Account details, usage and limits (account scope for Me()). |
client.Log(buildOrRunID) |
*LogClient |
Read or stream a build/run log. |
API errors are returned as *APIError, with the HTTP status, error type, message, attempt
count, and request method/path. get/delete on a missing resource is not an error: the
methods report absence via a boolean (ok) instead.
user, ok, err := client.Me().Get(ctx)
if err != nil {
if apiErr, isAPI := apify.AsAPIError(err); isAPI {
fmt.Printf("API error %d (%s): %s\n", apiErr.StatusCode, apiErr.Type, apiErr.Message)
}
log.Fatal(err)
}
if !ok {
log.Fatal("user not found")
}The transport is replaceable. Implement HTTPBackend (a single Do method) to integrate a
custom client, proxy, or test double, and pass it with WithHTTPBackend:
package main
import (
"net/http"
apify "github.com/apify/apify-client-go"
)
// myBackend is a custom HTTPBackend wrapping a standard *http.Client.
type myBackend struct{ inner *http.Client }
func (b *myBackend) Do(req *http.Request) (*http.Response, error) {
return b.inner.Do(req)
}
func main() {
client := apify.NewClientWithOptions(
apify.WithToken("my-api-token"),
apify.WithHTTPBackend(&myBackend{inner: http.DefaultClient}),
)
_ = client
}apify.CLIENT_VERSION— the semantic version of this library.apify.API_SPEC_VERSION— the Apify OpenAPI spec version this client was built against (v2-2026-06-23T113219Z).
Go modules are distributed by pushing a semver git tag — there is no separate package registry to
upload to. The Publish Go client workflow is the release
mechanism: a maintainer triggers it manually (workflow_dispatch), it runs the same quality gate
as CI, then creates and pushes the v<CLIENT_VERSION> tag, opens a GitHub release, and asks the Go
module proxy to index the new version so it appears on
pkg.go.dev. The tag is derived from
CLIENT_VERSION in version.go, so bump that constant before releasing. The workflow
uses only the built-in GITHUB_TOKEN; no extra credentials are required.
Runnable examples live in examples/ and are exercised in CI. Run any of them
with your token:
APIFY_TOKEN=<your-token> go run ./examples/run_store_actor| Example | Description |
|---|---|
get_account |
Fetch and print the current account details. |
storages |
Create, write to, and read from a dataset, key-value store, and request queue. |
run_store_actor |
Run a Store Actor, wait for it, and read its default dataset. |
run_and_last_run_storages |
Start a run, then fetch the Actor's last run and its storages. |
iterate_store |
Lazily iterate Actors in the Apify Store. |
log_redirection |
Start an Actor and stream its log in real time. |
create_build_run_actor |
Create an Actor, build it, run it, and print the run log. |
Per-resource guides are in docs/:
actors, builds, runs,
tasks, storages, schedules,
webhooks, misc (store, users, logs).
The client implements only documented API endpoints. Matching the JavaScript reference (and the Rust sibling) for cross-client consistency, the following documented endpoints are intentionally not implemented:
- Synchronous run endpoints (
run-sync,run-sync-get-dataset-items). - The keyed-
POSTrecord aliases. - Cryptographic tools:
POST /v2/tools/encode-and-signandPOST /v2/tools/decode-and-verify. These are server-side conveniences for the same HMAC signing this client already performs locally insignature.go; the reference clients do not expose them, so the Go client omits them too for parity. (Should a future requirement need them, they can be added alongsidesignature.go.) /v2/browser-info. Not exposed by the reference clients; omitted for parity.
This is a deliberate, parity-driven decision, not an accidental gap. See the CHANGELOG for the same note.
Licensed under the Apache License, Version 2.0. See LICENSE.