Telyvar

Calling a capability

There is no SDK to install and no key to request from us. Every capability is published on a channel that already handles discovery, authentication and billing, and you call it there with the account you already have.

Three ways in

1. The console, if you are a person

Open the capability on the channel and fill in the form. The fields are the ones listed on each capability's page, the channel renders them from the same schema, and it shows you the price before you press run. This is the fastest way to find out whether a capability does what you need, and it costs the same as any other route.

2. One HTTP request, if you are a program

The channel exposes every capability as a single endpoint that runs it and returns the results in the response body. The input JSON is the request body, and the shape is exactly what the capability's page describes.

POST https://api.apify.com/v2/acts/<owner>~<name>/run-sync-get-dataset-items
Content-Type: application/json
Authorization: Bearer <your own channel token>

Two properties of that endpoint are worth knowing before you depend on it. It is synchronous: the connection stays open for the length of the run, so your HTTP client needs a connection timeout long enough to survive it. And the channel gives it 300 seconds; a run that exceeds them returns 408 rather than a partial result, which is why every capability here caps how many items one call accepts.

3. As a tool, if you are an agent

The channel runs an MCP server at https://mcp.apify.com over streamable HTTP. An agent connected to it can search the catalogue, read a capability's input schema and call it, without anyone writing an integration first. That is the case these capabilities are built for.

One detail decides whether an agent can reach a capability at all: the channel's MCP server excludes full-permission capabilities, because running one is a decision a person is expected to approve personally. Everything here is limited-permission — each run touches only its own storage — which is what keeps it in reach of an agent.

What comes back

One row per item, in the order you sent them, each carrying the index it came from. A row for an item that failed is written too, with the rule it broke and where — so a caller can tell an item that could not be processed from one that was never reached. Alongside the rows, every run leaves a short report: delivered, succeeded, failed, not attempted, and whether it stopped early.

That last pair is the one to read. Not attempted above zero with stopped early true is a complete answer rather than a truncated one: your spending limit ended the run, and the run is telling you how many items it never got to. Nothing was silently dropped and nothing was charged for.

The capabilities, and what to send them

text.base64.transcode

Encodes and decodes base64 in either alphabet. Decoding is strict: input that is not well-formed base64 is refused with a reason and a position, instead of being silently repaired into bytes you did not send.

On the channel it is called text-base64-transcode.

Send:

{
  "direction": "decode",
  "alphabet": "standard",
  "items": [
    "VGVseXZhcg==",
    "VGVseXZhc$==",
    "VGVseXZhcg="
  ]
}

Get back — this is what the capability really returns for that input, not an illustration: its own test re-runs it and fails if this drifts.

{
  "results": [
    {
      "index": 0,
      "ok": true,
      "value": "Telyvar"
    },
    {
      "index": 1,
      "ok": false,
      "reason": "illegal-character",
      "detail": "position 9 is not a character of the standard alphabet"
    },
    {
      "index": 2,
      "ok": false,
      "reason": "bad-padding",
      "detail": "1 padding character does not complete a group of 10"
    }
  ],
  "report": {
    "delivered": 3,
    "succeeded": 1,
    "failed": 2,
    "notAttempted": 0,
    "stoppedEarly": false
  }
}

3 required fields: direction, alphabet, items. What each one means, or the same page as Markdown.

web.url.normalise

Says whether two URLs address the same thing, and names every change it made to decide. Malformed input is refused with a reason and a position instead of silently repaired: the standard parser deletes newlines, keeps a broken percent-escape as text, and encodes a raw space without saying so.

On the channel it is called url-normalise.

Send:

{
  "items": [
    "HTTPS://EXAMPLE.com:443/a/./b/../c?b=2&a=1#top",
    "https://example.com/a/c?b=2&a=1#top",
    "https://example.com/%zz"
  ],
  "also": [],
  "compareTo": "https://example.com/a/c?b=2&a=1#top"
}

Get back — this is what the capability really returns for that input, not an illustration: its own test re-runs it and fails if this drifts.

{
  "results": [
    {
      "index": 0,
      "ok": true,
      "url": "https://example.com/a/c?b=2&a=1#top",
      "scheme": "https",
      "host": "example.com",
      "hostAscii": "example.com",
      "changed": [
        "lowercased-scheme",
        "lowercased-host",
        "dropped-default-port",
        "resolved-dot-segments"
      ],
      "sameAsCompare": true
    },
    {
      "index": 1,
      "ok": true,
      "url": "https://example.com/a/c?b=2&a=1#top",
      "scheme": "https",
      "host": "example.com",
      "hostAscii": "example.com",
      "changed": [],
      "sameAsCompare": true
    },
    {
      "index": 2,
      "ok": false,
      "reason": "bad-percent-encoding",
      "detail": "position 20 is a % not followed by two hexadecimal digits, which the standard parser keeps as literal text"
    }
  ],
  "report": {
    "delivered": 3,
    "succeeded": 2,
    "failed": 1,
    "notAttempted": 0,
    "stoppedEarly": false
  }
}

1 required field: items. What each one means, or the same page as Markdown.

Limits

Two of them are ours and one is not. Each capability caps how many items one call accepts — the number is on its page, and it is the number that fits inside the channel's hard 300-second window rather than a licensing tier. Past that, a job is several calls.

The third is the channel's: it enforces its own rate limits against your account, the same ones that apply to everything else you run there. We do not add any of our own, and we could not raise theirs.

Versions

Each capability has its own version, its own changelog and its own release tag. They share a repository; they never share a release, so a change to one cannot move another.

The numbers mean what semantic versioning says they mean. A patch fixes behaviour that was wrong. A minor adds a field or an option without changing what an existing call does. A major changes something an existing caller depends on — a field that disappears, a default that moves, an input that stops being accepted. The version each capability is on today is on its page.

When something is wrong

Report it on the capability's own page on the channel, which carries an issue tracker against that specific capability. That is deliberately not an address here: an issue filed there is attached to the thing it is about, is visible to other callers who may have hit the same one, and reaches us through an account that already exists.

Two kinds of report are worth more than the rest. An input that was repaired instead of refused is the more serious of the two, because it is the failure these capabilities are built to prevent. An input that was refused and should not have been is the other. Include the item exactly as you sent it — the position in the error tells us where to look, but only against the original bytes.

Errors

A capability here refuses rather than repairs. An input that is not well-formed comes back with a reason and a position, and is not billed; it does not stop the items after it. That is the whole product in one sentence: the standard tool in each of these areas quietly fixes bad input and tells you nothing, and a repair you did not ask for is a wrong answer you cannot see.

Errors that end a whole run are the exception and they are declared per capability. Where one exists, it is because continuing would measure everything against something meaningless — and in that case the run stops before charging anything at all.

Where these facts come from

ClaimReferenceRead on
Run synchronously and get the results in the responsedocs.apify.com/api/v2/actor-run-sync-get-dataset-items-post2026-09-07
The channel's MCP server, and which capabilities it will not exposedocs.apify.com/integrations/mcp2026-09-07

Everything else on this page — the fields, the examples, the limits, what a run leaves behind — is generated from the capabilities themselves, so it cannot describe them differently from how they behave.