GraphQL Cursor Decoder

GraphQL Relay connections encode pagination cursors as Base64. The most common format is arrayconnection:<index> — so YXJyYXljb25uZWN0aW9uOjU= decodes to arrayconnection:5. Paste a cursor (from edges[].cursor, pageInfo.endCursor, or an after: argument) to decode it, or build one. Runs locally; nothing is uploaded.

CURSOR
DECODED
Waiting for input

How to decode a GraphQL cursor

A Relay cursor is just a Base64 string. Copy one from edges[].cursor, pageInfo.startCursor/pageInfo.endCursor, or an after:/before: argument, and paste it into the box above. The tool Base64-decodes it locally and shows the underlying value. In the vast majority of Relay APIs that value is arrayconnection:<index>. To go the other way and mint a cursor, toggle the button to Encode.

What is a Relay cursor?

A cursor is an opaque Base64 string that identifies a position in a connection. It comes from the Relay Cursor Connections spec, where every edge carries a cursor and the connection exposes pageInfo.startCursor and pageInfo.endCursor. You page through results by passing a cursor back to the server with the first/after arguments (forward) or last/before (backward). "Opaque" means you are not supposed to parse it — but because it is only Base64, you can.

The arrayconnection:N format

Nearly every Relay cursor you will ever see decodes to arrayconnection:<index>. That is because the reference library graphql-relay-js ships a cursorForObjectInConnection helper that Base64-encodes the literal string arrayconnection:<index>, where the number is the item's zero-based offset in the connection array. So arrayconnection:5 points at the sixth item. It is a convenience default, not a rule of the spec — but so many servers use graphql-relay-js unchanged that this format is effectively ubiquitous.

Custom cursor formats

Servers are free to put anything inside a cursor. Some encode a record id, some a small JSON payload (for keyset/seek pagination), and some a timestamp. When this tool finds JSON inside a cursor it pretty-prints it; otherwise it shows the raw decoded value so you can see whatever the server chose to stash there.

Are cursors secret?

No. Cursors are opaque, not encrypted or signed — they are plain Base64, so anyone can decode or forge one. Never trust a cursor as authorization and never assume a client cannot see or tamper with its contents. If a position needs to be tamper-proof, the server must sign or validate it; the cursor value alone proves nothing.

Is this private?

Yes. Decoding and encoding run fully in the browser with JavaScript — your cursor is processed locally and nothing is uploaded to any server. You can confirm in DevTools → Network: decoding a cursor fires no request.

Frequently asked questions

How do I decode a GraphQL/Relay cursor?

Paste the cursor from edges[].cursor, pageInfo.endCursor, or an after: argument into the input above. The tool Base64-decodes it locally and shows the underlying value — most commonly arrayconnection:<index>.

Why does my cursor decode to 'arrayconnection:5'?

That is the default format from graphql-relay-js. Its cursorForObjectInConnection helper Base64-encodes arrayconnection:<index>, where the number is the item's zero-based offset in the connection. So arrayconnection:5 is the sixth item.

Are GraphQL cursors encrypted or secure?

No — they are opaque Base64, which is trivially decoded and forged. Do not use a cursor as authorization or trust its contents as verified.

How do I create a cursor?

Switch the tool to Encode mode and type the value you want to wrap, for example arrayconnection:5. It is Base64-encoded into a cursor you can drop into an after: or before: argument.

My cursor decodes to gibberish/JSON — why?

Not every server uses the Relay array-connection format. Some use a custom, server-defined format — a record id, a JSON payload, or a timestamp. This tool pretty-prints JSON when it finds it and otherwise shows the raw decoded value.

Need plain Base64 encode/decode?

The main base64.dev tool handles text, files, and URL-safe mode with auto-detect.

Open base64.dev →