Skip to main content

manifest-api

Stop guessing selectors. Manifest tells your agent what's clickable, fillable, and submittable on any page.

Python SDK for the Manifest API — extracts structured action manifests from web pages so AI agents know what they can do, not just what's on screen.

Raw browser access Content extraction Manifest
Gives agents a browser
Returns page content
Returns available actions
Required fields, input types
Survives UI redesigns

Install

pip install manifest-api

Quickstart

Sync

from manifest_api import ManifestClient

client = ManifestClient(api_key="your-key")  # or set MANIFEST_API_KEY env var
manifest = client.get("https://example.com")

print(manifest.current_page_state)
print(manifest.actions)

# Convenience helpers
action = manifest.action("submit-form")
inputs = manifest.actions_of_type("input")
required = manifest.required_actions

# Cheap structural-change check (no LLM call, never cached)
fp = client.fingerprint("https://example.com")
print(fp.fingerprint)

Async

import asyncio
from manifest_api import AsyncManifestClient

async def main():
    async with AsyncManifestClient(api_key="your-key") as client:
        manifest = await client.get("https://example.com")
        print(manifest.current_page_state)

asyncio.run(main())

LangChain

pip install "manifest-api[langchain]"
from manifest_api.integrations.langchain import create_manifest_tool

tool = create_manifest_tool()  # reads MANIFEST_API_KEY from env
# or: create_manifest_tool(api_key="...")

# use with an agent, e.g.:
from langchain.agents import create_agent
agent = create_agent(model=..., tools=[tool])

create_manifest_tool wraps AsyncManifestClient as a get_manifest(url) StructuredTool — the API key is bound at creation time, so the LLM never sees it.

All methods

# Both ManifestClient and AsyncManifestClient expose:
manifest = client.get("https://example.com")          # POST /manifest → Manifest
fp       = client.fingerprint("https://example.com")  # POST /fingerprint → Fingerprint
health   = client.health()                             # GET  /health → dict
valid    = client.session_valid()                      # GET  /session-status → bool

Manifest helpers

manifest.action("id")              # → Action | None
manifest.actions_of_type("input")  # → list[Action]
manifest.required_actions          # → list[Action]
manifest.blocked_actions([...])    # → list[Action], see "Action dependencies" below
manifest.fingerprint               # → str | None, same hash `fingerprint()` returns

Fingerprint

fingerprint(url) runs the same page-render + extraction pipeline as get(url) but skips the LLM translation step, returning just a stable hash of the page's interactive surface (Fingerprint.fingerprint). Useful for cheaply polling whether a page's action surface has changed since your last get() call, without paying for another manifest generation. Every Manifest also carries this same hash on manifest.fingerprint, so you can compare it against a later fingerprint() call directly.

fp = client.fingerprint("https://example.com")
print(fp.url, fp.fingerprint)

Action dependencies

Some actions are disabled until others are completed (e.g. a submit button gated on required fields). Action.requires lists the ids of actions that must be completed first; blocked_actions() filters a manifest down to actions not yet unblocked by a given set of completed ids:

completed = ["email-input"]
still_blocked = manifest.blocked_actions(completed)  # actions still waiting on something

requires is inferred by the LLM translation step from DOM signals (disabled attributes, aria-disabled, form field proximity) — it's best-effort, not a guaranteed-accurate dependency graph, and won't capture custom JS validation logic.

Action types

button · input · textarea · select · checkbox · radio · other

Locators

Each action may carry a locator with css, role, and name — enough to find and act on the underlying element without guessing a selector yourself. It's best-effort: locator is None if no element on the page plausibly matched the action.

Prefer role/name over css where possible — they hold up better across redesigns, since css can be a brittle positional fallback when the element has no id or name attribute.

action = manifest.action("continue")
if action.locator and action.locator.css:
    page.click(action.locator.css)

Error handling

from manifest_api import AuthenticationError, RateLimitError, APIError

try:
    manifest = client.get("https://example.com")
except AuthenticationError:
    print("Check your API key")
except RateLimitError:
    print("Slow down — rate limit hit")
except APIError as e:
    print(f"Server error {e.status_code}")

Docs

https://omfang.io/manifest-docs

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

manifest_api-0.2.1.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

manifest_api-0.2.1-py3-none-any.whl (7.4 kB view details)

Uploaded Python 3

File details

Details for the file manifest_api-0.2.1.tar.gz.

File metadata

  • Download URL: manifest_api-0.2.1.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for manifest_api-0.2.1.tar.gz
Algorithm Hash digest
SHA256 3550816fc72188f4cb12529a08c2b0a5b4365aaf99dd19e2f28685e549171eb2
MD5 06b36c24c81572c0e195414bf7167d11
BLAKE2b-256 ddbec00f091acbcc22c1426ca0e5cb4c0baa1cc86e1aeed3fc9d521fdf8227aa

See more details on using hashes here.

File details

Details for the file manifest_api-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: manifest_api-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 7.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for manifest_api-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a91c306f463b240e04de091495aea120e30f74020dad96abe2ae85c79557fc11
MD5 e5ec971c2f91968d76282f1235025b75
BLAKE2b-256 cf3fa4cc20a9e6f1f0e830ba5b48ea4d0e44742d8f32fd2db70607d560265a6c

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page