qodev-apollo-cli 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qodev_apollo_cli-0.1.0/.github/workflows/ci.yml +35 -0
- qodev_apollo_cli-0.1.0/.github/workflows/publish.yml +46 -0
- qodev_apollo_cli-0.1.0/.gitignore +9 -0
- qodev_apollo_cli-0.1.0/CHANGELOG.md +42 -0
- qodev_apollo_cli-0.1.0/LICENSE +21 -0
- qodev_apollo_cli-0.1.0/PKG-INFO +224 -0
- qodev_apollo_cli-0.1.0/README.md +193 -0
- qodev_apollo_cli-0.1.0/pyproject.toml +89 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/__init__.py +3 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/__main__.py +5 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/app.py +120 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/__init__.py +0 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/accounts.py +51 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/calls.py +54 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/contacts.py +147 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/deals.py +51 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/emails.py +37 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/enrich.py +34 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/install.py +59 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/jobs.py +36 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/news.py +35 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/notes.py +68 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/people.py +34 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/pipelines.py +106 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/tasks.py +79 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/commands/usage.py +56 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/context.py +35 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/formatters/__init__.py +0 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/formatters/accounts.py +62 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/formatters/contacts.py +80 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/formatters/deals.py +46 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/formatters/generic.py +101 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/help_reference.py +123 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/output.py +150 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/skills/SKILL.md +200 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/skills/__init__.py +1 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/skills/references/__init__.py +1 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/skills/references/account-workflows.md +202 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/skills/references/contact-workflows.md +110 -0
- qodev_apollo_cli-0.1.0/src/apollo_cli/skills/references/deal-workflows.md +142 -0
- qodev_apollo_cli-0.1.0/tests/conftest.py +137 -0
- qodev_apollo_cli-0.1.0/tests/test_commands.py +223 -0
- qodev_apollo_cli-0.1.0/tests/test_context.py +73 -0
- qodev_apollo_cli-0.1.0/tests/test_install.py +47 -0
- qodev_apollo_cli-0.1.0/tests/test_output.py +137 -0
- qodev_apollo_cli-0.1.0/uv.lock +597 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
env:
|
|
9
|
+
UV_NO_SOURCES: "1"
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
lint:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: astral-sh/setup-uv@v4
|
|
17
|
+
- run: uv sync --all-extras
|
|
18
|
+
- run: uv run ruff check .
|
|
19
|
+
- run: uv run ruff format --check .
|
|
20
|
+
|
|
21
|
+
typecheck:
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- uses: astral-sh/setup-uv@v4
|
|
26
|
+
- run: uv sync --all-extras
|
|
27
|
+
- run: uv run mypy src/apollo_cli/
|
|
28
|
+
|
|
29
|
+
test:
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@v4
|
|
33
|
+
- uses: astral-sh/setup-uv@v4
|
|
34
|
+
- run: uv sync --all-extras
|
|
35
|
+
- run: uv run pytest -v
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
env:
|
|
8
|
+
UV_NO_SOURCES: "1"
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
lint:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
- uses: astral-sh/setup-uv@v4
|
|
16
|
+
- run: uv sync --all-extras
|
|
17
|
+
- run: uv run ruff check .
|
|
18
|
+
- run: uv run ruff format --check .
|
|
19
|
+
|
|
20
|
+
typecheck:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@v4
|
|
24
|
+
- uses: astral-sh/setup-uv@v4
|
|
25
|
+
- run: uv sync --all-extras
|
|
26
|
+
- run: uv run mypy src/apollo_cli/
|
|
27
|
+
|
|
28
|
+
test:
|
|
29
|
+
runs-on: ubuntu-latest
|
|
30
|
+
steps:
|
|
31
|
+
- uses: actions/checkout@v4
|
|
32
|
+
- uses: astral-sh/setup-uv@v4
|
|
33
|
+
- run: uv sync --all-extras
|
|
34
|
+
- run: uv run pytest -v
|
|
35
|
+
|
|
36
|
+
publish:
|
|
37
|
+
needs: [lint, typecheck, test]
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
environment: pypi
|
|
40
|
+
permissions:
|
|
41
|
+
id-token: write
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
- uses: astral-sh/setup-uv@v4
|
|
45
|
+
- run: uv build
|
|
46
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-02-26
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Initial CLI implementation with cyclopts framework
|
|
14
|
+
- Dual output mode: Markdown (default, agent/human-friendly) and JSON (`--json`)
|
|
15
|
+
- Global options: `--json`, `--api-key`, `--limit`, `--page`
|
|
16
|
+
- **contacts**: search, get, create, update, find-by-linkedin, stages
|
|
17
|
+
- **accounts**: search, get
|
|
18
|
+
- **deals**: search, get
|
|
19
|
+
- **pipelines**: list, get, stages
|
|
20
|
+
- **stages**: list (all stages across pipelines)
|
|
21
|
+
- **enrich**: org (free), person (1 credit)
|
|
22
|
+
- **people**: search (global database)
|
|
23
|
+
- **notes**: search, create
|
|
24
|
+
- **tasks**: search, create, complete
|
|
25
|
+
- **calls**: search, list (per contact)
|
|
26
|
+
- **emails**: search
|
|
27
|
+
- **news**: list (per account)
|
|
28
|
+
- **jobs**: list (per account)
|
|
29
|
+
- **usage**: API usage stats and rate limits
|
|
30
|
+
- **install**: Install AI agent skill files with `--skills` flag
|
|
31
|
+
- Centralized error handling with semantic exit codes (80-83)
|
|
32
|
+
- Rich markdown rendering for terminal output with `help_format="rich"`
|
|
33
|
+
- Pagination support with page/limit controls
|
|
34
|
+
- Comprehensive README.md with command reference and usage examples
|
|
35
|
+
- MIT License
|
|
36
|
+
- Full PyPI metadata in pyproject.toml
|
|
37
|
+
- CI/CD workflows (lint, typecheck, test, publish)
|
|
38
|
+
- Complete test suite with pytest and pytest-asyncio
|
|
39
|
+
- AI agent skill files (SKILL.md + workflow references)
|
|
40
|
+
- Dynamic help epilogue with all commands
|
|
41
|
+
- Dev dependencies (ruff, mypy, pytest)
|
|
42
|
+
- Tool configurations (ruff, mypy, pytest)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 qodev GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: qodev-apollo-cli
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Agent-friendly CLI for the Apollo API
|
|
5
|
+
Project-URL: Homepage, https://github.com/qodevai/apollo-cli
|
|
6
|
+
Project-URL: Repository, https://github.com/qodevai/apollo-cli
|
|
7
|
+
Project-URL: Issues, https://github.com/qodevai/apollo-cli/issues
|
|
8
|
+
Author-email: Jan Scheffler <jan.scheffler@qodev.ai>
|
|
9
|
+
License: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api,apollo,cli,contacts,crm,sales
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Typing :: Typed
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: cyclopts>=3.0
|
|
22
|
+
Requires-Dist: qodev-apollo-api>=0.1.0
|
|
23
|
+
Requires-Dist: rich>=13.0
|
|
24
|
+
Provides-Extra: dev
|
|
25
|
+
Requires-Dist: mypy>=1.13.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: pytest-asyncio>=0.25.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-mock>=3.15; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=9.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff>=0.15; extra == 'dev'
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
[](https://github.com/qodevai/apollo-cli/actions/workflows/ci.yml)
|
|
33
|
+
[](https://pypi.org/project/qodev-apollo-cli/)
|
|
34
|
+
|
|
35
|
+
# qodev-apollo-cli
|
|
36
|
+
|
|
37
|
+
Agent-friendly CLI for the Apollo.io API. Designed for both human and AI-agent workflows, with structured JSON output, consistent flags, and predictable error codes.
|
|
38
|
+
|
|
39
|
+
## Why this CLI?
|
|
40
|
+
|
|
41
|
+
- **Agent-friendly** — `--json` on every command, consistent flags, predictable exit codes
|
|
42
|
+
- **Built for AI agent workflows** — works seamlessly with Claude Code, scripts, and automation pipelines
|
|
43
|
+
- **Comprehensive** — Access contacts, accounts, deals, enrichment, tasks, notes, and more
|
|
44
|
+
- **Dual output modes** — Beautiful markdown tables for humans, structured JSON for agents
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install qodev-apollo-cli
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Or run directly without installing:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
uvx qodev-apollo-cli
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Set your Apollo API key
|
|
62
|
+
export APOLLO_API_KEY="your_api_key_here"
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
# Install AI agent skill files (for Claude Code, etc.)
|
|
67
|
+
$ qodev-apollo-cli install --skills
|
|
68
|
+
|
|
69
|
+
# Search contacts
|
|
70
|
+
$ qodev-apollo-cli contacts search --query "engineer" --limit 5
|
|
71
|
+
Jane Smith VP Engineering Acme Corp jane@acme.com
|
|
72
|
+
|
|
73
|
+
# Get contact details as JSON (for scripts/agents)
|
|
74
|
+
$ qodev-apollo-cli --json contacts get <contact-id>
|
|
75
|
+
{"id": "...", "name": "Jane Smith", "title": "VP Engineering", ...}
|
|
76
|
+
|
|
77
|
+
# Enrich a company (free)
|
|
78
|
+
$ qodev-apollo-cli enrich org acme.com
|
|
79
|
+
|
|
80
|
+
# Search deals in a specific stage
|
|
81
|
+
$ qodev-apollo-cli deals search --stage-id <stage-id>
|
|
82
|
+
|
|
83
|
+
# Check API usage
|
|
84
|
+
$ qodev-apollo-cli usage
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Commands
|
|
88
|
+
|
|
89
|
+
| Group | Subcommand | Description |
|
|
90
|
+
|---|---|---|
|
|
91
|
+
| **contacts** | `search` | Search contacts (`--query`, `--stage-id`, `--linkedin-url`) |
|
|
92
|
+
| | `get` | Get contact details by ID |
|
|
93
|
+
| | `create` | Create a new contact (`--first-name`, `--last-name`, `--email`, etc.) |
|
|
94
|
+
| | `update` | Update contact (`--title`, `--label-ids`) |
|
|
95
|
+
| | `find-by-linkedin` | Find contact by LinkedIn URL (`--create`, `--stage-id`) |
|
|
96
|
+
| | `stages` | List all contact stages |
|
|
97
|
+
| **accounts** | `search` | Search companies/accounts (`--query`, `--domain`) |
|
|
98
|
+
| | `get` | Get account details by ID |
|
|
99
|
+
| **deals** | `search` | Search opportunities/deals (`--query`, `--stage-id`) |
|
|
100
|
+
| | `get` | Get deal details by ID |
|
|
101
|
+
| **pipelines** | `list` | List all deal pipelines |
|
|
102
|
+
| | `get` | Get pipeline details |
|
|
103
|
+
| | `stages` | List stages in a pipeline |
|
|
104
|
+
| **stages** | `list` | List all contact stages |
|
|
105
|
+
| | `get` | Get stage details |
|
|
106
|
+
| **enrich** | `org` | Enrich organization by domain (FREE - no credits) |
|
|
107
|
+
| | `person` | Enrich person by email (1 credit per lookup) |
|
|
108
|
+
| **people** | `search` | Search people database (`--person-titles`, `--q-organization-domains`) |
|
|
109
|
+
| **notes** | `search` | Search notes (`--contact-id`) |
|
|
110
|
+
| | `create` | Create a note (`--contact-ids`, `--note`) |
|
|
111
|
+
| **tasks** | `search` | Search tasks (`--type`, `--status`) |
|
|
112
|
+
| | `create` | Create a task (`--contact-ids`, `--note`, `--due-at`) |
|
|
113
|
+
| **calls** | `search` | Search call activities |
|
|
114
|
+
| **emails** | `search` | Search email activities |
|
|
115
|
+
| **news** | `search` | Search news (`--categories`) |
|
|
116
|
+
| **jobs** | `search` | Search job postings (`--job-titles`, `--company-domains`) |
|
|
117
|
+
| **usage** | (default) | Show API usage stats and rate limits |
|
|
118
|
+
| **install** | `--skills` | Install AI agent skill files to `.claude/skills/apollo/` |
|
|
119
|
+
|
|
120
|
+
## Configuration
|
|
121
|
+
|
|
122
|
+
### Authentication
|
|
123
|
+
|
|
124
|
+
Set the `APOLLO_API_KEY` environment variable, or pass `--api-key` on each invocation:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
export APOLLO_API_KEY="your_api_key_here"
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Get your API key from [Apollo.io Settings → API](https://app.apollo.io/#/settings/integrations/api).
|
|
131
|
+
|
|
132
|
+
### Global Options
|
|
133
|
+
|
|
134
|
+
| Flag | Description | Default |
|
|
135
|
+
|---|---|---|
|
|
136
|
+
| `--json` | Output as JSON (for scripting / agents) | `false` |
|
|
137
|
+
| `--api-key` | Apollo API key (overrides `APOLLO_API_KEY`) | |
|
|
138
|
+
| `--limit` | Results per page | `25` |
|
|
139
|
+
| `--page` | Page number | `1` |
|
|
140
|
+
|
|
141
|
+
### Exit Codes
|
|
142
|
+
|
|
143
|
+
| Code | Meaning |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `0` | Success |
|
|
146
|
+
| `80` | Authentication error (invalid API key) |
|
|
147
|
+
| `81` | Rate limit exceeded |
|
|
148
|
+
| `82` | API error (server error, invalid request) |
|
|
149
|
+
| `83` | Validation error (missing required fields) |
|
|
150
|
+
|
|
151
|
+
## JSON Output
|
|
152
|
+
|
|
153
|
+
All commands support `--json` for structured output:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
qodev-apollo-cli --json contacts search --query "engineer" | jq '.items[0].name'
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Paginated responses include:
|
|
160
|
+
|
|
161
|
+
```json
|
|
162
|
+
{
|
|
163
|
+
"items": [...],
|
|
164
|
+
"total": 142,
|
|
165
|
+
"page": 1,
|
|
166
|
+
"limit": 25
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Common Workflows
|
|
171
|
+
|
|
172
|
+
### Find and enrich a contact
|
|
173
|
+
|
|
174
|
+
```bash
|
|
175
|
+
# Search by keyword
|
|
176
|
+
qodev-apollo-cli contacts search --query "jane smith"
|
|
177
|
+
|
|
178
|
+
# Get full details
|
|
179
|
+
qodev-apollo-cli contacts get <contact-id>
|
|
180
|
+
|
|
181
|
+
# Enrich person data (1 credit)
|
|
182
|
+
qodev-apollo-cli enrich person jane@example.com
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
### Pipeline management
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
# List all pipelines
|
|
189
|
+
qodev-apollo-cli pipelines list
|
|
190
|
+
|
|
191
|
+
# Get stages in a pipeline
|
|
192
|
+
qodev-apollo-cli pipelines stages <pipeline-id>
|
|
193
|
+
|
|
194
|
+
# Search deals in specific stage
|
|
195
|
+
qodev-apollo-cli deals search --stage-id <stage-id>
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### LinkedIn integration
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
# Find contact by LinkedIn URL
|
|
202
|
+
qodev-apollo-cli contacts find-by-linkedin "https://linkedin.com/in/janesmith"
|
|
203
|
+
|
|
204
|
+
# Auto-create if not found
|
|
205
|
+
qodev-apollo-cli contacts find-by-linkedin "https://linkedin.com/in/janesmith" --create
|
|
206
|
+
|
|
207
|
+
# Assign to stage on creation
|
|
208
|
+
qodev-apollo-cli contacts find-by-linkedin "https://linkedin.com/in/janesmith" \
|
|
209
|
+
--create --stage-id <stage-id>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Company enrichment (FREE)
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Enrich by domain (no credits used)
|
|
216
|
+
qodev-apollo-cli enrich org acme.com
|
|
217
|
+
|
|
218
|
+
# View as JSON
|
|
219
|
+
qodev-apollo-cli --json enrich org acme.com | jq '.industry'
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT -- see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
[](https://github.com/qodevai/apollo-cli/actions/workflows/ci.yml)
|
|
2
|
+
[](https://pypi.org/project/qodev-apollo-cli/)
|
|
3
|
+
|
|
4
|
+
# qodev-apollo-cli
|
|
5
|
+
|
|
6
|
+
Agent-friendly CLI for the Apollo.io API. Designed for both human and AI-agent workflows, with structured JSON output, consistent flags, and predictable error codes.
|
|
7
|
+
|
|
8
|
+
## Why this CLI?
|
|
9
|
+
|
|
10
|
+
- **Agent-friendly** — `--json` on every command, consistent flags, predictable exit codes
|
|
11
|
+
- **Built for AI agent workflows** — works seamlessly with Claude Code, scripts, and automation pipelines
|
|
12
|
+
- **Comprehensive** — Access contacts, accounts, deals, enrichment, tasks, notes, and more
|
|
13
|
+
- **Dual output modes** — Beautiful markdown tables for humans, structured JSON for agents
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install qodev-apollo-cli
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or run directly without installing:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
uvx qodev-apollo-cli
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Set your Apollo API key
|
|
31
|
+
export APOLLO_API_KEY="your_api_key_here"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
# Install AI agent skill files (for Claude Code, etc.)
|
|
36
|
+
$ qodev-apollo-cli install --skills
|
|
37
|
+
|
|
38
|
+
# Search contacts
|
|
39
|
+
$ qodev-apollo-cli contacts search --query "engineer" --limit 5
|
|
40
|
+
Jane Smith VP Engineering Acme Corp jane@acme.com
|
|
41
|
+
|
|
42
|
+
# Get contact details as JSON (for scripts/agents)
|
|
43
|
+
$ qodev-apollo-cli --json contacts get <contact-id>
|
|
44
|
+
{"id": "...", "name": "Jane Smith", "title": "VP Engineering", ...}
|
|
45
|
+
|
|
46
|
+
# Enrich a company (free)
|
|
47
|
+
$ qodev-apollo-cli enrich org acme.com
|
|
48
|
+
|
|
49
|
+
# Search deals in a specific stage
|
|
50
|
+
$ qodev-apollo-cli deals search --stage-id <stage-id>
|
|
51
|
+
|
|
52
|
+
# Check API usage
|
|
53
|
+
$ qodev-apollo-cli usage
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
| Group | Subcommand | Description |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| **contacts** | `search` | Search contacts (`--query`, `--stage-id`, `--linkedin-url`) |
|
|
61
|
+
| | `get` | Get contact details by ID |
|
|
62
|
+
| | `create` | Create a new contact (`--first-name`, `--last-name`, `--email`, etc.) |
|
|
63
|
+
| | `update` | Update contact (`--title`, `--label-ids`) |
|
|
64
|
+
| | `find-by-linkedin` | Find contact by LinkedIn URL (`--create`, `--stage-id`) |
|
|
65
|
+
| | `stages` | List all contact stages |
|
|
66
|
+
| **accounts** | `search` | Search companies/accounts (`--query`, `--domain`) |
|
|
67
|
+
| | `get` | Get account details by ID |
|
|
68
|
+
| **deals** | `search` | Search opportunities/deals (`--query`, `--stage-id`) |
|
|
69
|
+
| | `get` | Get deal details by ID |
|
|
70
|
+
| **pipelines** | `list` | List all deal pipelines |
|
|
71
|
+
| | `get` | Get pipeline details |
|
|
72
|
+
| | `stages` | List stages in a pipeline |
|
|
73
|
+
| **stages** | `list` | List all contact stages |
|
|
74
|
+
| | `get` | Get stage details |
|
|
75
|
+
| **enrich** | `org` | Enrich organization by domain (FREE - no credits) |
|
|
76
|
+
| | `person` | Enrich person by email (1 credit per lookup) |
|
|
77
|
+
| **people** | `search` | Search people database (`--person-titles`, `--q-organization-domains`) |
|
|
78
|
+
| **notes** | `search` | Search notes (`--contact-id`) |
|
|
79
|
+
| | `create` | Create a note (`--contact-ids`, `--note`) |
|
|
80
|
+
| **tasks** | `search` | Search tasks (`--type`, `--status`) |
|
|
81
|
+
| | `create` | Create a task (`--contact-ids`, `--note`, `--due-at`) |
|
|
82
|
+
| **calls** | `search` | Search call activities |
|
|
83
|
+
| **emails** | `search` | Search email activities |
|
|
84
|
+
| **news** | `search` | Search news (`--categories`) |
|
|
85
|
+
| **jobs** | `search` | Search job postings (`--job-titles`, `--company-domains`) |
|
|
86
|
+
| **usage** | (default) | Show API usage stats and rate limits |
|
|
87
|
+
| **install** | `--skills` | Install AI agent skill files to `.claude/skills/apollo/` |
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
### Authentication
|
|
92
|
+
|
|
93
|
+
Set the `APOLLO_API_KEY` environment variable, or pass `--api-key` on each invocation:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
export APOLLO_API_KEY="your_api_key_here"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Get your API key from [Apollo.io Settings → API](https://app.apollo.io/#/settings/integrations/api).
|
|
100
|
+
|
|
101
|
+
### Global Options
|
|
102
|
+
|
|
103
|
+
| Flag | Description | Default |
|
|
104
|
+
|---|---|---|
|
|
105
|
+
| `--json` | Output as JSON (for scripting / agents) | `false` |
|
|
106
|
+
| `--api-key` | Apollo API key (overrides `APOLLO_API_KEY`) | |
|
|
107
|
+
| `--limit` | Results per page | `25` |
|
|
108
|
+
| `--page` | Page number | `1` |
|
|
109
|
+
|
|
110
|
+
### Exit Codes
|
|
111
|
+
|
|
112
|
+
| Code | Meaning |
|
|
113
|
+
|---|---|
|
|
114
|
+
| `0` | Success |
|
|
115
|
+
| `80` | Authentication error (invalid API key) |
|
|
116
|
+
| `81` | Rate limit exceeded |
|
|
117
|
+
| `82` | API error (server error, invalid request) |
|
|
118
|
+
| `83` | Validation error (missing required fields) |
|
|
119
|
+
|
|
120
|
+
## JSON Output
|
|
121
|
+
|
|
122
|
+
All commands support `--json` for structured output:
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
qodev-apollo-cli --json contacts search --query "engineer" | jq '.items[0].name'
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Paginated responses include:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"items": [...],
|
|
133
|
+
"total": 142,
|
|
134
|
+
"page": 1,
|
|
135
|
+
"limit": 25
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Common Workflows
|
|
140
|
+
|
|
141
|
+
### Find and enrich a contact
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
# Search by keyword
|
|
145
|
+
qodev-apollo-cli contacts search --query "jane smith"
|
|
146
|
+
|
|
147
|
+
# Get full details
|
|
148
|
+
qodev-apollo-cli contacts get <contact-id>
|
|
149
|
+
|
|
150
|
+
# Enrich person data (1 credit)
|
|
151
|
+
qodev-apollo-cli enrich person jane@example.com
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Pipeline management
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# List all pipelines
|
|
158
|
+
qodev-apollo-cli pipelines list
|
|
159
|
+
|
|
160
|
+
# Get stages in a pipeline
|
|
161
|
+
qodev-apollo-cli pipelines stages <pipeline-id>
|
|
162
|
+
|
|
163
|
+
# Search deals in specific stage
|
|
164
|
+
qodev-apollo-cli deals search --stage-id <stage-id>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### LinkedIn integration
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
# Find contact by LinkedIn URL
|
|
171
|
+
qodev-apollo-cli contacts find-by-linkedin "https://linkedin.com/in/janesmith"
|
|
172
|
+
|
|
173
|
+
# Auto-create if not found
|
|
174
|
+
qodev-apollo-cli contacts find-by-linkedin "https://linkedin.com/in/janesmith" --create
|
|
175
|
+
|
|
176
|
+
# Assign to stage on creation
|
|
177
|
+
qodev-apollo-cli contacts find-by-linkedin "https://linkedin.com/in/janesmith" \
|
|
178
|
+
--create --stage-id <stage-id>
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### Company enrichment (FREE)
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
# Enrich by domain (no credits used)
|
|
185
|
+
qodev-apollo-cli enrich org acme.com
|
|
186
|
+
|
|
187
|
+
# View as JSON
|
|
188
|
+
qodev-apollo-cli --json enrich org acme.com | jq '.industry'
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## License
|
|
192
|
+
|
|
193
|
+
MIT -- see [LICENSE](LICENSE) for details.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "qodev-apollo-cli"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Agent-friendly CLI for the Apollo API"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
authors = [{ name = "Jan Scheffler", email = "jan.scheffler@qodev.ai" }]
|
|
8
|
+
license = { text = "MIT" }
|
|
9
|
+
keywords = ["apollo", "crm", "cli", "api", "sales", "contacts"]
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Development Status :: 4 - Beta",
|
|
12
|
+
"Intended Audience :: Developers",
|
|
13
|
+
"License :: OSI Approved :: MIT License",
|
|
14
|
+
"Programming Language :: Python :: 3",
|
|
15
|
+
"Programming Language :: Python :: 3.11",
|
|
16
|
+
"Programming Language :: Python :: 3.12",
|
|
17
|
+
"Programming Language :: Python :: 3.13",
|
|
18
|
+
"Typing :: Typed",
|
|
19
|
+
]
|
|
20
|
+
dependencies = [
|
|
21
|
+
"cyclopts>=3.0",
|
|
22
|
+
"rich>=13.0",
|
|
23
|
+
"qodev-apollo-api>=0.1.0",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
dev = [
|
|
28
|
+
"pytest>=9.0",
|
|
29
|
+
"pytest-asyncio>=0.25.0",
|
|
30
|
+
"pytest-mock>=3.15",
|
|
31
|
+
"ruff>=0.15",
|
|
32
|
+
"mypy>=1.13.0",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.scripts]
|
|
36
|
+
qodev-apollo-cli = "apollo_cli.app:main"
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/qodevai/apollo-cli"
|
|
40
|
+
Repository = "https://github.com/qodevai/apollo-cli"
|
|
41
|
+
Issues = "https://github.com/qodevai/apollo-cli/issues"
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["hatchling"]
|
|
45
|
+
build-backend = "hatchling.build"
|
|
46
|
+
|
|
47
|
+
[tool.hatch.build.targets.wheel]
|
|
48
|
+
packages = ["src/apollo_cli"]
|
|
49
|
+
|
|
50
|
+
[tool.uv.sources]
|
|
51
|
+
qodev-apollo-api = { path = "../../libs/apollo" }
|
|
52
|
+
|
|
53
|
+
[tool.ruff]
|
|
54
|
+
target-version = "py311"
|
|
55
|
+
line-length = 120
|
|
56
|
+
|
|
57
|
+
[tool.ruff.lint]
|
|
58
|
+
select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
|
|
59
|
+
ignore = ["E501"]
|
|
60
|
+
|
|
61
|
+
[tool.ruff.lint.isort]
|
|
62
|
+
known-first-party = ["apollo_cli"]
|
|
63
|
+
|
|
64
|
+
[tool.mypy]
|
|
65
|
+
python_version = "3.11"
|
|
66
|
+
warn_return_any = false
|
|
67
|
+
warn_unused_configs = true
|
|
68
|
+
disallow_untyped_defs = false
|
|
69
|
+
no_implicit_optional = true
|
|
70
|
+
warn_redundant_casts = true
|
|
71
|
+
warn_unused_ignores = true
|
|
72
|
+
warn_no_return = true
|
|
73
|
+
check_untyped_defs = true
|
|
74
|
+
strict_optional = true
|
|
75
|
+
|
|
76
|
+
[[tool.mypy.overrides]]
|
|
77
|
+
module = "qodev_apollo_api.*"
|
|
78
|
+
ignore_missing_imports = true
|
|
79
|
+
|
|
80
|
+
[[tool.mypy.overrides]]
|
|
81
|
+
module = "cyclopts.*"
|
|
82
|
+
ignore_missing_imports = true
|
|
83
|
+
|
|
84
|
+
[tool.pytest.ini_options]
|
|
85
|
+
testpaths = ["tests"]
|
|
86
|
+
|
|
87
|
+
[tool.ruff.format]
|
|
88
|
+
quote-style = "double"
|
|
89
|
+
indent-style = "space"
|