Skip to main content

Official Python SDK for the WellMarked API — convert any URL to clean Markdown.

Project description

wellmarked

PyPI Python

Official Python SDK for the WellMarked API — convert any URL to clean Markdown.

pip install wellmarked

Quick start

from wellmarked import WellMarked

with WellMarked(api_key="wm_...") as wm:
    result = wm.extract("https://example.com/article")
    print(result.markdown)
    print(result.metadata.title, "by", result.metadata.author)

The API key can also be picked up from the WELLMARKED_API_KEY environment variable, in which case WellMarked() is enough.

Get a key at wellmarked.io.

Pricing

Free Pro Enterprise
Price $0 $19/mo $99/mo
Included Requests 500/mo 5,000/mo 30,000/mo
Bulk Requests ✅ (up to 50/request) ✅ (Unlimited)
Overage Rate $0.004/req $0.002/req
JS Rendering
Priority Queue Standard High Highest

See additional pricing information at WellMarked

Async

AsyncWellMarked is a drop-in async equivalent — every endpoint method is a coroutine.

import asyncio
from wellmarked import AsyncWellMarked

async def main():
    async with AsyncWellMarked() as wm:
        result = await wm.extract("https://example.com/article")
        print(result.markdown)

asyncio.run(main())

Bulk extraction

Submit many URLs at once (Pro: up to 50; Enterprise: unlimited). The call returns immediately with a job_id. Poll with get_job or block until done with wait_for_job.

job = wm.bulk([
    "https://example.com/article-1",
    "https://example.com/article-2",
])
job = wm.wait_for_job(job.job_id)         # blocks until status == "done"

for item in job.results:
    if item.ok:
        print(item.metadata.title)
    else:
        print(f"{item.url} failed: {item.error}")

Usage & rate limits

get_usage() is the source of truth for your current-period quota. The quota state belongs on the account, so call get_usage() when you want it:

usage = wm.get_usage()
print(f"{usage.used} / {usage.limit} used this period ({usage.plan}) — {usage.remaining} left")

GET /usage itself does not count toward your quota.

Key rotation

rotated = wm.rotate_key()
print("New key:", rotated.api_key)  # shown once — store it before the program exits

After rotate_key() the client automatically switches to the new key for subsequent calls; you still need to persist rotated.api_key somewhere durable, because the previous key stops working immediately and there is no recovery flow.

Errors

Every non-2xx response is translated into a typed exception. Catch the base class to handle anything, or the specific subclass to handle one failure mode:

from wellmarked import (
    WellMarked,
    AuthenticationError,
    PermissionDeniedError,
    NotFoundError,
    UnprocessableEntityError,
    RateLimitError,
    APIConnectionError,
)

with WellMarked() as wm:
    try:
        result = wm.extract("https://example.com/paywalled")
    except RateLimitError as e:
        print(f"Quota hit. Resets in {e.retry_after}s.")
    except UnprocessableEntityError as e:
        # e.code is one of: no_content, target_timeout, js_rendering_disabled, ...
        print(f"Extraction failed ({e.code}): {e.message}")
Exception HTTP Typical code values
AuthenticationError 401 missing_api_key, invalid_api_key
PermissionDeniedError 403 account_inactive, plan_not_supported, forbidden
NotFoundError 404 job_not_found
UnprocessableEntityError 422 no_content, target_timeout, js_rendering_disabled, bulk_cap_exceeded
RateLimitError 429 rate_limit_exceeded (carries retry_after in seconds)
InternalServerError 5xx
APIConnectionError DNS / TCP / TLS / timeout failures, raised before any HTTP round-trip

All inherit from WellMarkedError.

Configuration

WellMarked(
    api_key="wm_...",                   # or set WELLMARKED_API_KEY
    base_url="https://api.wellmarked.io",
    timeout=30.0,                       # seconds, per request
    http_client=my_httpx_client,        # optional: bring your own httpx.Client
)

Passing your own httpx.Client/httpx.AsyncClient is useful for custom transports, proxies, or shared connection pools. When you do, the SDK won't close it on __exit__ — you remain responsible for its lifecycle.

For Agents

If you are an agent, feel free to find additional context here!

License

MIT

Project details


Download files

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

Source Distribution

wellmarked-1.0.0.tar.gz (10.7 kB view details)

Uploaded Source

Built Distribution

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

wellmarked-1.0.0-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file wellmarked-1.0.0.tar.gz.

File metadata

  • Download URL: wellmarked-1.0.0.tar.gz
  • Upload date:
  • Size: 10.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wellmarked-1.0.0.tar.gz
Algorithm Hash digest
SHA256 1ef63f51cd87cbddcdaad1127107004370b93034f4d64be7eba00381e87d55c9
MD5 9e6aaf903fa33eb0e84fdcc9e3a44c14
BLAKE2b-256 a62f28ad3922b3fb79a630bb2dfcd2eaaf30582a7cbc0017707e86cde0f14f93

See more details on using hashes here.

Provenance

The following attestation bundles were made for wellmarked-1.0.0.tar.gz:

Publisher: publish-sdk.yml on gradill22/WellMarked

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file wellmarked-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: wellmarked-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 14.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for wellmarked-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 a2b757e81e7d09cb536d101745273cee566f7d6609f19951ab1e23dc25631f13
MD5 48c13c939ed3d81453226be6ace9d1af
BLAKE2b-256 fe8dbbde6b635c8ba7e47024b242fac45cd8784522a4c9bd6ada49a379b2b965

See more details on using hashes here.

Provenance

The following attestation bundles were made for wellmarked-1.0.0-py3-none-any.whl:

Publisher: publish-sdk.yml on gradill22/WellMarked

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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