Skip to content

feat: add apify api subcommand for direct API access#1076

Merged
patrikbraborec merged 8 commits intomasterfrom
feat/apify-api-subcommand
Apr 22, 2026
Merged

feat: add apify api subcommand for direct API access#1076
patrikbraborec merged 8 commits intomasterfrom
feat/apify-api-subcommand

Conversation

@patrikbraborec
Copy link
Copy Markdown
Contributor

Summary

Adds apify api — a general-purpose authenticated HTTP client for the Apify API, inspired by gh api.

  • apify api v2/users/me — make authenticated GET requests
  • apify api v2/acts --method POST --body '{...}' — create resources
  • apify api --list-endpoints — browse all 129 API endpoints (from bundled OpenAPI spec)

Features

  • HTTP methods via --method / -X (GET, POST, PUT, PATCH, DELETE)
  • Request body via --body / -d (JSON string or stdin with -)
  • Custom headers via --header / -H
  • --list-endpoints / -l — lists all available endpoints with color-coded methods and descriptions, powered by the Apify OpenAPI spec fetched at build time

Closes #1075

🤖 Generated with Claude Code

@github-actions github-actions Bot added t-c&c Team covering store and finance matters. tested Temporary label used only programatically for some analytics. labels Apr 8, 2026
@patrikbraborec patrikbraborec added t-dx Issues owned by the DX team. and removed t-c&c Team covering store and finance matters. labels Apr 8, 2026
patrikbraborec and others added 4 commits April 15, 2026 15:06
Add a general-purpose authenticated HTTP client for the Apify API,
similar to `gh api` in GitHub CLI. Supports GET/POST/PUT/PATCH/DELETE
methods, request body (including stdin), custom headers, and a
--list-endpoints flag powered by the bundled OpenAPI spec.

Closes #1075

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add missing `return` after `printHelp()` to prevent fetch with undefined endpoint
- Make build resilient to network failures by falling back to committed api-endpoints.json
- Commit api-endpoints.json so fresh checkouts work without network access
- Wrap test cleanup in try/finally to prevent actor leak on assertion failure

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…y params, and lint fix

Add support for positional HTTP method syntax (e.g. `apify api GET /v2/users/me`),
auto-prepend `v2/` prefix when omitted, add `--params` flag for query parameters,
use `getLoggedClientOrThrow` for auth, switch to `simpleLog` for output, validate
JSON body before sending, and fix prefer-destructuring lint error.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tighten input validation in `apify api`: extract parseParams/parseHeaders
helpers, support multi-header JSON form, reject nested/non-scalar query
params, and detect conflicts between the positional HTTP method and the
--method flag. Derive the base URL from apifyClient.baseUrl so the v2
prefix and APIFY_CLIENT_BASE_URL are handled in one place, and hint at
--list-endpoints on 404 responses.

Register the command in the docs generator (and regenerate docs). Move
fetch-api-endpoints out of `build` into `prepack` so local builds do not
require network access.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@patrikbraborec patrikbraborec force-pushed the feat/apify-api-subcommand branch from 1ab31a3 to 3ab62dd Compare April 15, 2026 14:08
@patrikbraborec patrikbraborec marked this pull request as ready for review April 15, 2026 14:10
useConsoleSpy sets restoreMocks: false, so spy.mock.calls accumulates
across tests. Reading calls[0][0] returned the first test's v2/users/me
response on every subsequent test — passing by coincidence when checking
.data.id/.username, failing when checking .data.items or .data.name.
Switch to logMessages.log[0], which resets per test.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Comment thread src/commands/api.ts
Comment thread package.json Outdated
Copy link
Copy Markdown
Contributor

@l2ysho l2ysho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No other concern except of one Vlad pointed to, about download of endpoints list on demand. Maybe we can cache it in some clever way? cc @vladfrangu

@patrikbraborec
Copy link
Copy Markdown
Contributor Author

Ok, I would probably go with a call fetch API endpoints when user/agent calls --list-endpoints. If we see performance issues, we can cache it. Cc. @vladfrangu

@vladfrangu
Copy link
Copy Markdown
Member

Lets go for downloading on demand for now, and in the future we can probably have an fs cache (but not bundling it in CLI)

Download https://docs.apify.com/api/openapi.json at runtime when
--list-endpoints is used, instead of bundling a pre-generated
api-endpoints.json. Drops the prepack fetch step and the fetch-api-endpoints
script so the list can no longer go stale between releases.

While here, address staff-review findings on the apify api command:

- ^v2\/? could over-strip paths like "v2things/x"; require a trailing slash
  and accept it case-insensitively.
- --body was silently sent on GET/HEAD, triggering an unfriendly fetch
  TypeError. Reject early with a clear validation message.
- Custom headers could duplicate Content-Type due to case differences; apply
  overrides case-insensitively.
- On non-2xx responses, write the JSON response body to stdout (matches
  gh api) so pipelines like `apify api ... | jq` still receive the payload;
  status line stays on stderr.
- Document the one-header-per-invocation restriction in --header.
- Reset process.exitCode in beforeEach and capture actorId before
  assertions so the api-tests don't pass on inherited state or leak actors
  when an assertion fails.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@l2ysho l2ysho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

Comment thread src/commands/api.ts
patrikbraborec and others added 2 commits April 22, 2026 14:57
Moves the inline example blocks out of the description and into the
framework's `examples` field (added in #1080) so they render as the
standard shell-comment EXAMPLES block, matching every other command.
Also wires up `docsUrl` to surface the API reference in LEARN MORE.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@patrikbraborec patrikbraborec merged commit da15ae7 into master Apr 22, 2026
23 checks passed
@patrikbraborec patrikbraborec deleted the feat/apify-api-subcommand branch April 22, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-dx Issues owned by the DX team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add apify api subcommand as a general-purpose authenticated HTTP client for the Apify API

5 participants