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/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.0.tar.gz (7.5 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.0-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for manifest_api-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7f3f7b68ad93864940156f844b9a29c335b30637e6409c48ac0b25f440b18ddf
MD5 f8e80043c9d29896f41ceceb46633e5b
BLAKE2b-256 07ef82cd83018ee6de9c36c7f0f144434eee694fc3d6affeb7d82d3cb0d6e0e0

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for manifest_api-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 250a790f87f1f3fba5898fd231a95bb6ba41314f3284dbb52cc8c4e7f1e1aee5
MD5 0a1e27ce4da29d8cddb5ac53c124d99e
BLAKE2b-256 df34f5d8866eeaf81cfedf82013e2912ae6978369ed9494b860663751f156ad8

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