Skip to main content

Extract URLs API

Pull every link out of a text, without the trailing punctuation, deduplicated, one per line.

EndpointPOST https://astraltext.com/api/v1/extract-urls
AuthBearer token, free
Sendsinput: text
Returnsresult: text
PriceFree. 1,000 calls a day, 60 a minute.

When to call it

Link auditing, migration checks and citation lists all start with the same step: getting the URLs out of prose that was not written to be parsed. Doing it as a call means the answer is the same for a blog post, an email and a model's output.

For a one-off, the browser version needs no token and never sends your data anywhere: it runs on your own machine.

Example

curl
curl -X POST https://astraltext.com/api/v1/extract-urls \
  -H "Authorization: Bearer ast_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"input": "See https://example.com/a and http://example.org/b?x=1. Again: https://example.com/a"}'
response
{
  "tool": "extract-urls",
  "result": "https://example.com/a\nhttp://example.org/b?x=1",
  "chars": 46,
  "ms": 1
}

In your language

JavaScript
const res = await fetch("https://astraltext.com/api/v1/extract-urls", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ASTRAL_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({"input": "See https://example.com/a and http://example.org/b?x=1. Again: https://example.com/a"}),
});
if (!res.ok) throw new Error((await res.json()).detail);
const { result } = await res.json();
Python
import os, requests

res = requests.post(
    "https://astraltext.com/api/v1/extract-urls",
    headers={"Authorization": f"Bearer {os.environ['ASTRAL_TOKEN']}"},
    json={"input": "See https://example.com/a and http://example.org/b?x=1. Again: https://example.com/a"},
    timeout=30,
)
res.raise_for_status()
result = res.json()["result"]

Parameters

FieldTypeNotes
inputstringRequired. Up to 200,000 characters per call.

Errors

Errors are RFC 7807 problem documents with a stable type you can branch on.

missing-token401No Authorization header.
bad-request400input missing or the wrong type.
tool-failed422The input could not be processed. detail says why.
quota-exceeded429Past 1,000 calls today.

Questions

Are trailing punctuation marks included?
No. A full stop or a closing bracket that ends the sentence is not part of the URL and is left behind.
Are duplicates removed?
Yes, and order is preserved: each URL appears once, where it first appeared.
Does it find bare domains?
It finds URLs with a scheme. A bare domain in prose is ambiguous, and guessing produces more false positives than it is worth.

Other endpoints

A token takes thirty seconds

Free, no card, 1,000 calls a day, and the same token works on astraltext.com, astralpdf.com, astraljson.com and astralbatch.com.

Get a free token