Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,37 @@ All notable changes to the Apify Go client are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.4.1] - 2026-06-29

Documentation-only compliance pass against the current orchestration requirements (no spec bump;
the client remains on `v2-2026-06-25T142310Z`). No change to the public API surface, so this is a
SemVer patch.

### Changed

- Documentation now states the client is **official, but experimental** and **AI-generated and
AI-maintained**, replacing the previous "not (yet) an officially supported Apify product"
wording that contradicted the requirement. Updated consistently in `README.md`, `docs/README.md`,
and the package-level doc comment in `client.go`.
- `README.md` "Releasing" section now explicitly documents that Go's publishing process has no
central registry and therefore no "Trusted Publisher" mechanism — releases are cut purely by
pushing a git tag read by the public Go module proxy, authenticated only by the built-in
`GITHUB_TOKEN`. The `go-publish.yml` workflow already reflected this; the README now matches.
- Documentation completeness pass (no API change): added a field table for `*APIError` and
documented `AsAPIError` in `README.md`; added a `RunChargeOptions` field table and a note that
`MetamorphOptions`/`RunChargeOptions` use plain (non-pointer) values in `docs/runs.md`;
enumerated the webhook `Create` input keys in `docs/webhooks.md`; documented the request-queue
locking method signatures (`ListAndLockHead`, `ProlongRequestLock`, `DeleteRequestLock`,
`UnlockRequests`) in `docs/storages.md`.

### Fixed

- Corrected a stale `API_SPEC_VERSION` reference in the `README.md` "Versioning" section
(`v2-2026-06-24T105326Z` → `v2-2026-06-25T142310Z`) so it matches `version.go`.
- `docs/storages.md`: `DownloadItems` now lists `JSONL` in its format list, matching the format
constants table (previously the prose omitted it).
- Bumped `CLIENT_VERSION` to `0.4.1` (patch; documentation-only, no public API change).

## [0.4.0] - 2026-06-26

Updated to Apify OpenAPI specification `v2-2026-06-25T142310Z` (previously
Expand Down
32 changes: 25 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Apify API client for Go

> **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.
> **Official, but experimental — AI-generated and AI-maintained.** This is an official Apify
> client, but it is experimental: it is generated and maintained by AI. Review the code before
> relying on it in production and report issues on the repository.

An idiomatic Go client for the [Apify API](https://docs.apify.com/api/v2).

Expand Down Expand Up @@ -116,9 +116,21 @@ variable the JavaScript reference client reads); if it is set to a non-empty val

## Error handling

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.
API errors are returned as `*APIError`. Recover it from any returned `error` with
`apify.AsAPIError(err) (*APIError, bool)` — the boolean is `false` when the error is not an API
error (e.g. a network or context error). `get`/`delete` on a missing resource is *not* an error:
the methods report absence via a boolean (`ok`) instead.

`*APIError` exposes:

| Field | Type | Meaning |
|---|---|---|
| `StatusCode` | `int` | HTTP status code of the error response. |
| `Type` | `string` | Machine-readable error type returned by the API (e.g. `"record-not-found"`). |
| `Message` | `string` | Human-readable error description returned by the API. |
| `Attempt` | `int` | 1-based number of the API call attempt that produced this error. |
| `HTTPMethod` | `string` | HTTP method of the failing call (e.g. `"GET"`, `"POST"`). |
| `Path` | `string` | Request path of the endpoint (URL excluding origin). |

```go
user, ok, err := client.Me().Get(ctx)
Expand Down Expand Up @@ -167,7 +179,7 @@ func main() {

- `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-24T105326Z`).
(`v2-2026-06-25T142310Z`).

### Releasing

Expand All @@ -180,6 +192,12 @@ module proxy to index the new version so it appears on
`CLIENT_VERSION` in [`version.go`](version.go), so bump that constant before releasing. The workflow
uses only the built-in `GITHUB_TOKEN`; no extra credentials are required.

There is no "Trusted Publisher" step: that mechanism applies to registries that authenticate
uploads (e.g. PyPI, npm, crates.io). Go has no central registry and no upload step — a module is
published purely by pushing a git tag that the public module proxy reads — so there is no token or
trusted-publisher relationship to configure. The workflow therefore relies only on the repository's
built-in `GITHUB_TOKEN` to push the tag and open the release.

## Examples

Runnable examples live in [`examples/`](examples) and are exercised in CI. Run any of them
Expand Down
4 changes: 4 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Package apify is the official, idiomatic Go client for the Apify API
// (https://docs.apify.com/api/v2).
//
// Official, but experimental — AI-generated and AI-maintained. This is an official Apify
// client, but it is experimental: it is generated and maintained by AI. Review the code
// before relying on it in production and report issues on the repository.
//
// 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
Expand Down
6 changes: 3 additions & 3 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Apify Go client documentation

> **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.
> **Official, but experimental — AI-generated and AI-maintained.** This is an official Apify
> client, but it is experimental: it is generated and maintained by AI. Review the code before
> relying on it in production and report issues on the repository.

This directory documents the public API of the Apify Go client, organized by resource. Each
page lists the available methods with their parameters and short, runnable snippets. For an
Expand Down
14 changes: 12 additions & 2 deletions docs/runs.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,18 @@ The time filters apply only to Actor- and task-scoped collections.
| `Build` | `string` | Pin the target Actor's build (empty for default). |
| `ContentType` | `string` | Content type of the input body (default `application/json`). |

`RunChargeOptions`: `EventName` (required), `Count`, `IdempotencyKey` (auto-generated if
empty, so a retried charge is applied at most once).
`RunChargeOptions`:

| Field | Type | Meaning |
|---|---|---|
| `EventName` | `string` | Name of the event to charge for. **Required.** |
| `Count` | `*int64` | Number of times to charge the event (defaults to 1 when nil). |
| `IdempotencyKey` | `string` | Deduplicates the charge across retries; auto-generated when empty, so a retried charge is applied at most once. |

> Note: unlike most option structs (whose optional fields are pointer-typed — see
> [docs/README.md](README.md)), `MetamorphOptions` and the string fields of `RunChargeOptions`
> use plain values. `Build`/`ContentType` and `EventName`/`IdempotencyKey` treat the zero value
> (empty string) as "unset"; only `RunChargeOptions.Count` is a pointer.

```go
run, err := client.Run(runID).WaitForFinish(ctx, nil) // nil waits indefinitely
Expand Down
7 changes: 5 additions & 2 deletions docs/storages.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Single dataset: `client.Dataset(id)`:
| `Get / Update / Delete(ctx)` | CRUD. |
| `ListItems(ctx, DatasetListItemsOptions) (PaginationList[json.RawMessage], error)` | Read items. |
| `PushItems(ctx, items any) error` | Append one item or a slice of items. |
| `DownloadItems(ctx, DownloadItemsFormat, DatasetDownloadOptions) ([]byte, error)` | Export items (JSON, CSV, XLSX, XML, RSS, HTML). |
| `DownloadItems(ctx, DownloadItemsFormat, DatasetDownloadOptions) ([]byte, error)` | Export items (JSON, JSONL, CSV, XLSX, XML, RSS, HTML — see the format constants below). |
| `GetStatistics(ctx) (json.RawMessage, bool, error)` | Dataset statistics. |
| `CreateItemsPublicURL(ctx, DatasetListItemsOptions, expiresInSecs *int64) (string, error)` | Signed public items URL. |

Expand Down Expand Up @@ -188,7 +188,10 @@ Single queue: `client.RequestQueue(id)`:
| `PaginateRequests(pageLimit *int64) *RequestQueueRequestsIterator` | Lazy iterator over all requests (yields `*RequestQueueRequest`). |
| `BatchAddRequests(ctx, []RequestQueueRequest, forefront) (BatchAddResult, error)` | Add many requests (auto-chunked at 25/call). |
| `BatchDeleteRequests(ctx, requests any) (json.RawMessage, error)` | Delete many requests in one call. `requests` is the JSON-marshalable batch payload — a slice in which each element identifies one request by **either** its `id` **or** its `uniqueKey` (e.g. `[]map[string]string{{"uniqueKey": "..."}}` or a slice of `RequestQueueRequest`), matching the reference client's `batchDeleteRequests`. Returns the raw API response. |
| `ListAndLockHead / ProlongRequestLock / DeleteRequestLock / UnlockRequests(ctx, ...)` | Locking. |
| `ListAndLockHead(ctx, lockSecs int64, limit *int64) (json.RawMessage, error)` | Fetch the head of the queue and lock the returned requests for `lockSecs` seconds. Returns the raw API response. |
| `ProlongRequestLock(ctx, id string, lockSecs int64, forefront bool) (json.RawMessage, error)` | Extend the lock on a request by `lockSecs` seconds; `forefront` controls re-queue position when the lock expires. |
| `DeleteRequestLock(ctx, id string, forefront bool) error` | Release the lock on a request without modifying it. |
| `UnlockRequests(ctx) (json.RawMessage, error)` | Release all locks held by this client (see `WithClientKey`). |
| `WithClientKey(key string) *RequestQueueClient` | Pin a stable client key (required to unlock own locks). |

`RequestQueueRequest` is the request payload/record. `URL` is required; `ID` is assigned by the
Expand Down
12 changes: 12 additions & 0 deletions docs/webhooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ Webhooks notify external services when events occur. Access the webhook collecti
An Actor's or task's webhooks are also listable via `client.Actor(id).Webhooks()` /
`client.Task(id).Webhooks()`.

`Create` (and `Update`) take a free-form JSON object (`any`) that mirrors the webhook shape in
the Apify API, so it can carry any field the API accepts. The commonly used input keys are:

| Key | Type | Meaning |
|---|---|---|
| `eventTypes` | `[]string` | Events that trigger the webhook (see [Event types](#event-types)). Required. |
| `requestUrl` | `string` | URL the webhook posts to. Required. |
| `condition` | `object` | Scope the webhook, e.g. `{"actorId": "..."}`, `{"actorTaskId": "..."}`, or `{"actorRunId": "..."}`. |
| `isAdHoc` | `bool` | `true` for a one-off webhook bound to a single run/build via `condition`. |
| `payloadTemplate` | `string` | Optional template string for the dispatched payload. |
| `description` | `string` | Optional human-readable description. |

### Event types

A webhook's `eventTypes` is a list drawn from the closed `WebhookEventType` enum (12 values):
Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package apify
//
// It follows Semantic Versioning (https://semver.org/). Changes to the public
// interface (other than additive ones) are considered breaking changes.
const CLIENT_VERSION = "0.4.0"
const CLIENT_VERSION = "0.4.1"

// API_SPEC_VERSION is the version of the Apify OpenAPI specification that this
// client was generated and verified against.
Expand Down
Loading