otxcli
Python library and CLI covering every endpoint of the AlienVault OTX v1 API
Overview
otxcli is a Python toolkit to query and manage threat intelligence on AlienVault OTX. Every endpoint documented in the OTX v1 API is implemented: indicator lookups, file/URL submissions, pulse management, search, and user actions — usable both as a command-line tool and as a typed Python library.
Key Features
| Feature | Description |
|---|---|
| Complete API coverage | All 40 documented OTX v1 operations |
| CLI + Library | Use as command-line tool or Python package |
| Indicator lookups | IPv4, IPv6, domain, hostname, file hash, URL, CVE, NIDS, correlation rule — with every section |
| Submissions | Submit files and URLs for analysis, list them, manage their TLP |
| Pulse management | Create, edit, delete, subscribe, related pulses, feeds, events |
| IDN aware | Internationalized domains resolve via UTS46 punycode, the same rules a browser applies |
| Clean errors | OTXError with status and detail; CLI always exits 1 with a message, never a traceback |
| Cross-platform | Windows, Linux and macOS, x64 and ARM |
| Battle-tested | Integration suite runs against the live API with 100% coverage and no mocks |
Supported Outputs
CLI Pretty-printed JSON on stdout, errors on stderr
Library Decoded JSON (dict/list) per call, OTXError on failure
Installation
From PyPI (Recommended)
pip install otxcli
From Source
git clone https://github.com/seifreed/otxcli.git
cd otxcli
python3 -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e .
Quick Start
Get an API key from your OTX account settings and export it:
export OTX_API_KEY=your-key-here
# Validate your API key
otx me
# Look up an indicator
otx ipv4 8.8.8.8
# Search pulses
otx search-pulses zeus --limit 5
Usage
Command Line Interface
# Indicator sections
otx ipv4 8.8.8.8 --section reputation
otx domain rghost.net --section malware
otx file 6c5360d41bd2b14b1565f5b18e5c203cf512e493 --section analysis
otx url http://example.com/ --section url_list
otx cve CVE-2014-0160
# Submissions
otx submit-url http://example.com/ --tlp white
otx submit-file suspicious.bin
otx submitted-files --limit 10 --sort add_date
# Pulses
otx pulse 57204e9b3c4c3e015d93cb12
otx create-pulse '{"name": "My pulse", "public": true, "TLP": "white"}'
otx edit-pulse 57204e9b3c4c3e015d93cb12 '{"description": "New description"}'
otx subscribed-pulses --limit 10 --modified-since 2026-01-01T00:00:00+00:00
# Users
otx subscribe-to-user AlienVault
Available Commands
| Command group | Commands |
|---|---|
| Indicators | ipv4, ipv6, domain, hostname, file, url, cve, nids, correlation-rule |
| Submissions | submit-file, submit-url, submit-urls, submitted-files, submitted-urls, update-submitted-files-tlp, update-submitted-urls-tlp |
| Pulses | pulse, create-pulse, edit-pulse, delete-pulse, pulse-indicators, pulse-related, related-pulses, subscribe-to-pulse, unsubscribe-from-pulse, subscribed-pulses, subscribed-pulse-ids, activity, events, my-pulses, user-pulses, indicator-types, validate-indicator |
| Search | search-pulses, search-users |
| Users | me, subscribe-to-user, unsubscribe-from-user, follow-user, unfollow-user |
Run otx --help for the full list and otx <command> --help for the options of a
specific command.
Global Options
| Option | Description |
|---|---|
--api-key <key> |
OTX API key (defaults to the OTX_API_KEY environment variable) |
--server <host> |
API server host (defaults to otx.alienvault.com) |
--timeout <seconds> |
Request timeout in seconds (defaults to 120) |
Python Library
Basic Usage
from otxcli import OTXClient
client = OTXClient("your-key-here")
client.me()
client.ipv4("8.8.8.8", section="reputation")
client.domain("rghost.net", section="malware")
client.search_pulses("zeus", limit=5)
pulse = client.create_pulse({"name": "My pulse", "public": True, "TLP": "white"})
client.edit_pulse(pulse["id"], {"description": "New description"})
client.delete_pulse(pulse["id"])
Every method returns the decoded JSON response, or None when the endpoint answers
with an empty body. HTTP errors and unparseable responses raise otxcli.OTXError,
which carries status and detail attributes.
Internationalized Domains
domain and hostname accept internationalized names: OTX only resolves ASCII hosts,
so the name is converted to punycode with UTS46 mapping, the same rules a browser
applies. client.domain("bücher.de") looks up xn--bcher-kva.de, and a homograph such
as ᴳoogle.com reaches google.com rather than a lookalike nobody serves. ASCII
hostnames are sent exactly as given.
Requirements
- Python 3.14+
- One runtime dependency:
idna— see pyproject.toml
Development
All dependencies (runtime and development) live in pyproject.toml:
pip install -e '.[dev]'
Quality and security gates, all of which must pass clean:
black --check .
ruff check .
mypy .
bandit -r .
pip-audit
Tests run against the live OTX API (no mocks) and require OTX_API_KEY:
export OTX_API_KEY=your-key-here
pytest
Coverage below 100% fails the build.
Contributing
Contributions are welcome.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Support the Project
If this project is useful in your workflows, you can support development:
License
This project is licensed under the MIT license. See LICENSE.
Attribution
- Author: Marc Rivero López | @seifreed
- Repository: github.com/seifreed/otxcli
Built for practical threat intelligence workflows and security automation
Metadata
Release files for otxcli 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| otxcli-0.1.2.tar.gz | 20.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| otxcli-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.6 kB
Release files / otxcli-0.1.2.tar.gz
| Download URL | otxcli-0.1.2.tar.gz |
|---|---|
| Size | 20.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b69fe1f21012d0aada7c0c7a6ff8d2912ff13029a0f97cc4caacf4806384eda4
|
|
BLAKE2b-256 checksum How to use checksums |
be2c97a14bd211638e2877503374051e9da6581691383f0a05e066c5e4fa13f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency logRelease files / otxcli-0.1.2-py3-none-any.whl
| Download URL | otxcli-0.1.2-py3-none-any.whl |
|---|---|
| Size | 12.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
35f828c6e1b1af6dafa588edce20e35471c9b40f51bbff02a6b2b15194ab23ca
|
|
BLAKE2b-256 checksum How to use checksums |
410e06e84cc12236ccf78452f33a5b041795e268692c9de0e1d099619af68855
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.
Transparency log