# Access

> Connect to the Indexer via direct ClickHouse, custom REST APIs, or Python ETL.

Three ways to query the Indexer, picked by your workload.

<Note>
**Auth model:** every request needs both HTTP Basic (database `user` / `password`) **and** the `x-token` header. Missing or invalid `x-token` returns `403 Forbidden`.
</Note>

## How to get credentials

<Warning>
v1 access is **request-based**, not self-service. We provision manually after review.
</Warning>

<Steps>
  <Step title="Submit a request">
    Request access via Telegram: [@supanode_tgs](https://t.me/supanode_tgs).
  </Step>
  <Step title="Receive credentials">
    After review, we issue your `x-token` plus database username and password.
  </Step>
  <Step title="Connect">
    Use those credentials with the connection details below.
  </Step>
</Steps>

## Pick your access path

<CardGroup cols={3}>
  <Card title="Direct ClickHouse" icon="database" href="#direct-clickhouse">
    Full SQL, your own queries, scheduled jobs.
  </Card>
  <Card title="Custom REST API" icon="webhook" href="#custom-rest-api">
    Recurring queries deployed as stable endpoints.
  </Card>
  <Card title="Python ETL" icon="arrows-rotate" href="#python-etl-flows">
    Batch jobs, materialized aggregates, warehouse pushes.
  </Card>
</CardGroup>

## Direct ClickHouse

### Connection details

| Property | Value |
|---|---|
| Host | `soldata.supanode.xyz` |
| Port | `29001` |
| Protocol | HTTPS / TLS 1.2+ |

### Authentication layers

Two layers required on every request:

1. **Database credentials** - HTTP Basic Auth (`user` / `password`).
2. **API token** - `x-token` header.

### First connection (curl)

<Steps>
  <Step title="Run the test query">
    ```bash
    curl -H "x-token: YOUR_TOKEN" \
      'https://soldata.supanode.xyz:29001/?user=YOUR_USER&password=YOUR_PASSWORD' \
      -d "SELECT version(), now(), 'Connect Success' as status"
    ```
  </Step>
  <Step title="Verify response">
    If you get rows back, your connection and both auth layers are working.
  </Step>
</Steps>

### Code samples

<Tabs>
  <Tab title="Node.js">
    ```javascript
    import { createClient } from '@clickhouse/client';

    const client = createClient({
      url: 'https://soldata.supanode.xyz:29001',
      username: 'YOUR_USER',
      password: 'YOUR_PASSWORD',
      http_headers: { 'x-token': 'YOUR_TOKEN' },
      tls: { rejectUnauthorized: false },
    });

    const result = await client.query({
      query: `
        SELECT signature, slot, signing_wallet, fee_paid
        FROM pumpfun_all_swaps
        WHERE block_date_utc = today()
        ORDER BY slot DESC
        LIMIT 10
      `,
      format: 'JSONEachRow',
    });

    console.log(await result.json());
    ```
  </Tab>
  <Tab title="Python">
    The Python client requires injecting `x-token` via the underlying connection pool:

    ```python
    import clickhouse_connect
    from clickhouse_connect.driver import httputil

    # Inject the x-token header into all requests
    original_urlopen = httputil.PoolManager.urlopen
    def urlopen_with_token(self, *args, **kwargs):
        kwargs.setdefault('headers', {})
        kwargs['headers']['x-token'] = 'YOUR_TOKEN'
        return original_urlopen(self, *args, **kwargs)
    httputil.PoolManager.urlopen = urlopen_with_token

    client = clickhouse_connect.get_client(
        host='soldata.supanode.xyz',
        port=29001,
        secure=True,
        username='YOUR_USER',
        password='YOUR_PASSWORD',
    )

    result = client.query("""
        SELECT signature, slot, signing_wallet, fee_paid
        FROM pumpfun_all_swaps
        WHERE block_date_utc = today()
        ORDER BY slot DESC
        LIMIT 10
    """)

    for row in result.result_rows:
        print(row)
    ```
  </Tab>
  <Tab title="Go">
    ```go
    package main

    import (
        "context"
        "fmt"
        "github.com/ClickHouse/clickhouse-go/v2"
    )

    func main() {
        conn, err := clickhouse.Open(&clickhouse.Options{
            Addr: []string{"soldata.supanode.xyz:29001"},
            Auth: clickhouse.Auth{
                Username: "YOUR_USER",
                Password: "YOUR_PASSWORD",
            },
            Protocol: clickhouse.HTTP,
            HttpHeaders: map[string]string{
                "x-token": "YOUR_TOKEN",
            },
        })
        if err != nil {
            panic(err)
        }

        rows, err := conn.Query(context.Background(), `
            SELECT signature, slot, signing_wallet, fee_paid
            FROM pumpfun_all_swaps
            WHERE block_date_utc = today()
            LIMIT 10
        `)
        if err != nil {
            panic(err)
        }
        defer rows.Close()

        for rows.Next() {
            var signature, signingWallet string
            var slot, fee uint64
            if err := rows.Scan(&signature, &slot, &signingWallet, &fee); err != nil {
                panic(err)
            }
            fmt.Printf("%s slot=%d wallet=%s fee=%d\n", signature, slot, signingWallet, fee)
        }
    }
    ```
  </Tab>
</Tabs>

## Custom REST API

For specific recurring queries you don't want to write each time, we deploy custom REST endpoints.

You define what data you need (which tables, what filters, what aggregations); we deploy a stable URL that returns it. Useful for dashboards, partner integrations, and AI-agent workflows.

<Tip>
**When to pick this over direct ClickHouse:** the same query runs over and over from many places, or non-engineers need access without learning SQL.
</Tip>

To request a custom REST API, contact us with:

- The query (or a sketch of what you need).
- Expected request volume.
- Authentication preference (`x-token`, public, OAuth - we can do most).

Contact: [@supanode_tgs](https://t.me/supanode_tgs).

## Python ETL flows

For batch transformations and scheduled aggregations beyond simple queries, we build custom Python ETL on top of the database.

Examples:

- Daily aggregates pushed to your warehouse.
- Custom indicators computed and stored as new tables.
- Cross-protocol joins materialized for low-latency reads.

Same contact path: [@supanode_tgs](https://t.me/supanode_tgs).

## See also

<CardGroup cols={2}>
  <Card title="Database schema" icon="database" href="https://supanode.xyz/docs/solana/indexer/database-schema">
    All tables and columns.
  </Card>
  <Card title="Nanosecond timestamps" icon="stopwatch" href="https://supanode.xyz/docs/solana/indexer/nanosecond-timestamp">
    Precision arrival data.
  </Card>
</CardGroup>
