> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://docs.prividium.com/api/mcp` to find what you need.
>
> **Have feedback?** Use `submit_feedback` on the same MCP server.

This document explains how external services (such as indexers) can integrate with Prividium to access chain data and
verify user permissions.

:::note[NOTE]
Prividium is moving machine-to-machine integrations toward
[M2M applications](/configuring/applications/m2m-applications).
New integrations should authenticate as an M2M app with an API key and use the
[M2M app query endpoints](/configuring/applications/m2m-applications#query-endpoints) instead of the service-token
flow
described here. The service-token flow documented below remains supported during migration.
:::

## Overview

Services can integrate with Prividium in two ways:

1. **Service RPC Endpoint** - Access chain data for indexing (blocks, logs, transactions)
2. **Check Read Access Endpoint** - Verify if a user has read permissions before serving data

## Service Authentication

Services authenticate using a service token in the `Authorization` header. The Prividium™ API validates that the caller
is a registered service entity before processing requests.

:::note[NOTE]
Service tokens are distinct from user tokens. A service must be registered as an entity with type `service` in the
Permissions API.
:::

## Service RPC Access

### Available Methods

The following JSON-RPC methods are available for services (typically used for chain indexing):

| Method                      | Description                     |
| --------------------------- | ------------------------------- |
| `eth_blockNumber`           | Get the current block number    |
| `eth_getLogs`               | Query event logs with filters   |
| `eth_getTransactionByHash`  | Get transaction details by hash |
| `eth_getTransactionReceipt` | Get transaction receipt by hash |
| `eth_getBlockByNumber`      | Get a block by block number     |

### Example Request

```bash
curl -X POST http://localhost:8000/rpc \
  -H "Authorization: Bearer <service_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "eth_blockNumber",
    "params": [],
    "id": 1
  }'
```

### Example Response

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x1a2b3c"
}
```

## Verifying User Read Access

When a service needs to serve indexed data to a user, it should verify that the user has read permissions.

### Endpoint

```
POST http://localhost:8000/api/service-actions/check-read-access
```

### Request Body

| Field    | Type   | Required | Description                     |
| -------- | ------ | -------- | ------------------------------- |
| `userId` | string | Yes      | The user ID to check access for |

### Response

| Field        | Type    | Description                                       |
| ------------ | ------- | ------------------------------------------------- |
| `authorized` | boolean | `true` if user has read access, `false` otherwise |

### Permission Logic

A user has `fullReadAccess` if any of the following conditions are met:

* User has the `admin` role
* User has the `full_read_access` system permission

### Example Request

```bash
curl -X POST http://localhost:8000/api/service-actions/check-read-access \
  -H "Authorization: Bearer <service_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "userId": "user_123456"
  }'
```

### Example Response

```json
{
  "authorized": true
}
```

## Integration Flow

A typical integration flow for a webhook service:

```mermaid
sequenceDiagram
    participant U as User
    participant WS as Webhook Service
    participant PA as Permissions API

    %% Initial registration flow
    U->>WS: 1. Configure webhook<br/>+ send user session token
    WS->>PA: 2. GET /api/profiles/me<br/>(user session token)
    PA-->>WS: { user profile with userId }

    WS->>PA: 3. POST /check-read-access<br/>(userId)
    PA-->>WS: { authorized: true/false }

    alt Access denied
        WS-->>U: Error: user not allowed to register webhook
    else Access granted
        WS->>WS: 4. Store userId + params<br/>and enqueue webhook
    end

    %% Periodic permission re-check
    rect rgba(200, 200, 200, 0.15)
        note over WS: Webhook Service<br/>session token
        loop Periodic permission re-check
            WS->>PA: 5. POST /check-read-access<br/>(userId)
            PA-->>WS: { authorized: true/false }

            alt No longer allowed
                WS->>WS: Disable / mark webhook as inactive
            else Still allowed
                WS-->>WS: Keep webhook active (no-op)
            end
        end
    end
```

1. **Configure Webhook**: User sends webhook configuration along with their session token
2. **Identify User**: Service calls `GET /api/profiles/me` with the user's session token to retrieve the user profile
   and ID
3. **Check Access**: Service calls `POST /check-read-access` with the user ID to verify read permissions
4. **Store Configuration**: If access is granted, store the webhook configuration; otherwise, return an error
5. **Periodic Re-check**: Service periodically re-validates user permissions and disables webhooks for users who no
   longer have access
