Arweave gateways expose a GraphQL endpoint that lets you search, filter, and retrieve transactions by tags, owners, recipients, block height, and more. This is the primary way to discover and index data on the permaweb.
The GraphQL Endpoint
Every Arweave gateway provides a GraphQL endpoint:
https://arweave.net/graphql
Alternative endpoints for reliability:
https://arweave-search.goldsky.com/graphql(Goldsky indexer)https://g8way.io/graphql(alternative gateway)
Basic Query
Here's a query that fetches the 10 most recent transactions:
query {
transactions(first: 10, sort: HEIGHT_DESC) {
edges {
node {
id
owner {
address
}
tags {
name
value
}
block {
height
timestamp
}
}
}
}
}
Filtering by Tags
Tags are the primary way to find specific data on Arweave. Every transaction can have up to 2 KB of key-value tag metadata, and all of it is queryable.
Find HTML Content
query {
transactions(
tags: [
{ name: "Content-Type", values: ["text/html"] }
]
first: 10
) {
edges {
node {
id
tags {
name
value
}
}
}
}
}
Find Transactions from a Specific App
query {
transactions(
tags: [
{ name: "App-Name", values: ["My-App"] },
{ name: "App-Version", values: ["1.0.0"] }
]
first: 20
) {
edges {
node {
id
owner { address }
block { timestamp }
}
}
}
}
Multiple tag filters use AND logic, so all conditions must match.
Filtering by Owner
Find all transactions from a specific wallet address:
query {
transactions(
owners: ["M6w588ZkR8SVFdPkNXdBy4sqbMN0Y3F8ZJUWm2WCm8M"]
first: 10
) {
edges {
node {
id
tags {
name
value
}
}
}
}
}
Filtering by Block Height
Useful for finding transactions within a specific time range:
query {
transactions(
block: { min: 587540, max: 587550 }
first: 100
) {
edges {
node {
id
block {
height
timestamp
}
}
}
}
}
Pagination with Cursors
For large result sets, use cursor-based pagination:
query {
transactions(first: 10, after: "WyIyMDIzLTAxLTAxVDAwOjAwOjAwLjAwMFoiLDFd") {
pageInfo {
hasNextPage
}
edges {
cursor
node {
id
}
}
}
}
Use the cursor value from the last edge as the after parameter in the next query.
Using ar-gql (JavaScript Library)
The ar-gql library simplifies GraphQL queries from JavaScript:
Install
npm install ar-gql
Query Transactions
import { arGql } from 'ar-gql';
const gql = arGql();
// Find transactions by tag
const results = await gql.run(`
query {
transactions(
tags: [
{ name: "App-Name", values: ["My-App"] }
]
first: 10
) {
edges {
node {
id
owner { address }
tags { name value }
}
}
}
}
`);
for (const edge of results.data.transactions.edges) {
console.log('TX:', edge.node.id);
console.log('Owner:', edge.node.owner.address);
}
Paginate Automatically
const allResults = [];
let hasNextPage = true;
let cursor = '';
while (hasNextPage) {
const query = `query($cursor: String) {
transactions(
tags: [{ name: "App-Name", values: ["My-App"] }]
first: 100
after: $cursor
) {
pageInfo { hasNextPage }
edges {
cursor
node { id }
}
}
}`;
const result = await gql.run(query, { cursor });
const edges = result.data.transactions.edges;
allResults.push(...edges.map(e => e.node));
hasNextPage = result.data.transactions.pageInfo.hasNextPage;
cursor = edges[edges.length - 1]?.cursor || '';
}
Reading Transaction Data
Once you have a transaction ID, fetch its data directly:
// Via gateway HTTP
const response = await fetch(`https://arweave.net/${txId}`);
const data = await response.text();
// Via Arweave JS
import Arweave from 'arweave';
const arweave = Arweave.init({ host: 'arweave.net', port: 443, protocol: 'https' });
const data = await arweave.transactions.getData(txId, { decode: true, string: true });
Common Tag Patterns
Applications on Arweave use standardized tags for interoperability:
| Tag | Purpose | Example |
|---|---|---|
Content-Type |
MIME type for rendering | text/html, image/png |
App-Name |
Application identifier | My-App |
App-Version |
Version tracking | 1.0.0 |
Type |
Content classification | post, profile, comment |
Title |
Human-readable title | My First Post |
Unix-Time |
Timestamp (seconds) | 1704067200 |
Topic |
Content categorization | arweave, development |
Using consistent tags ensures your data is discoverable by other applications. This is what makes Arweave a shared, interoperable data layer rather than isolated storage.