---
source_url: https://www.pubnub.com/docs/sdks/c/api-reference/access-manager
title: Access Manager v3 API for C SDK
updated_at: 2026-09-24T12:25:41.000Z
sdk_name: PubNub C SDK
sdk_version: 1.0.0
---

# Access Manager v3 API for C SDK

PubNub C SDK, use the latest version: 1.0.0

## Documentation index

To discover more PubNub resources:

1. Fetch [PubNub's llms.txt](https://www.pubnub.com/llms-full.txt) for a list of available pages in Markdown format.
2. Identify relevant URLs from that index.
3. Fetch the target pages.

Do not assume a path exists, always check the index first.

Access Manager v3 (PAM) lets your servers grant PubNub clients time-limited tokens with embedded permissions, instead of exposing your keyset directly. A single `pubnub_grant_token()` call can cover any mix of resource types:

* `channels`
* `groups` (channel groups)
* `uuids` (other users' App Context metadata)

each granted either by exact resource name or by a RegEx pattern, with different permission levels per resource, all in one request. A token can be restricted to a single client through `authorized_uuid` and always carries a `ttl` after which it stops working.

Access Manager is compiled in only when the SDK is built with `PUBNUB_ENABLE_PAM`, which itself requires `PUBNUB_ENABLE_CRYPTO`:

:::warning PUBNUB_ENABLE_PAM requires PUBNUB_ENABLE_CRYPTO
Access Manager's request signing depends on the crypto provider. A build configured with `PUBNUB_ENABLE_PAM=ON` and `PUBNUB_ENABLE_CRYPTO=OFF` fails at CMake **configure** time with a fatal error, before any source file compiles. Enable `PUBNUB_ENABLE_CRYPTO` in every build that enables `PUBNUB_ENABLE_PAM`.
:::

:::warning Requires Secret Key authentication
Granting permissions to resources should be done by administrators whose SDK instance has been [initialized](https://www.pubnub.com/docs/sdks/c/api-reference/configuration.md) with a **Secret Key** (available on the [Admin Portal](https://admin.pubnub.com/) on your app's keyset).
:::

:::warning Secure your secret_key
Anyone who has your `secret_key` can grant and revoke permissions on every resource in your app. Never let `secret_key` be discovered, never place it in client-side code, and deliver it to your servers only over a secure channel. Once a context has a non-empty `secret_key` and the build enables `PUBNUB_ENABLE_PAM`, the SDK automatically signs every request that context sends. This includes grant, revoke, and everything else. There is no separate function to call to sign a request, and no way to opt out of signing while `secret_key` is set.
:::

## Grant token

:::note Requires Access Manager add-on
This function requires that the *Access Manager* add-on is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Read the [support page](https://support.pubnub.com/hc/en-us/articles/360051974791-How-do-I-enable-add-on-features-for-my-keys-) on enabling add-on features on your keys.
:::

`pubnub_grant_token()` asks the server to issue a token with an embedded access-control list. Permissions are bits from `pubnub_access_permission_t`, OR'd together and attached to a resource name or pattern through `pubnub_access_resource_permission_t`.

### Method(s)

```c
#include <pubnub/features/access.h>

pubnub_future_t pubnub_grant_token(pubnub_context_t* ctx, const pubnub_grant_token_opts_t* opts);
```

Permission bits (`pubnub_access_permission_t`), combined with bitwise OR into a `uint32_t`:

| Value | Numeric | Meaning |
| --- | --- | --- |
| `PUBNUB_ACCESS_READ` | 1 | Read messages and presence events. |
| `PUBNUB_ACCESS_WRITE` | 2 | Publish messages. |
| `PUBNUB_ACCESS_MANAGE` | 4 | Add or remove channels in channel groups. |
| `PUBNUB_ACCESS_DELETE` | 8 | Delete messages from history. |
| `PUBNUB_ACCESS_CREATE` | 16 | Create resources (App Context). |
| `PUBNUB_ACCESS_GET` | 32 | Read resource metadata (App Context). |
| `PUBNUB_ACCESS_UPDATE` | 64 | Update resource metadata (App Context). |
| `PUBNUB_ACCESS_JOIN` | 128 | Join a channel (presence). |

These values match the wire format directly. For example, `PUBNUB_ACCESS_READ` combined with `PUBNUB_ACCESS_WRITE` serializes as `3`. Not every bit is meaningful for every resource type. See [Manage Permissions with Access Manager v3](https://www.pubnub.com/docs/general/security/access-control.md#permissions) for the resource-to-permission mapping the server enforces.

Each resource entry (`pubnub_access_resource_permission_t`):

| Parameter | Description |
| --- | --- |
| `name`Type: `const char*` | Required, borrowed, NUL-terminated. An exact resource name, or a RegEx pattern string when the entry is placed in one of the pattern arrays below (for example `"^chat\\..*$"`). |
| `permissions`Type: `uint32_t` | One or more `pubnub_access_permission_t` values, combined with bitwise OR. |

Grant options (`pubnub_grant_token_opts_t`):

| Parameter | Description |
| --- | --- |
| `ttl` *Type: `uint32_t` | Minutes the token stays valid. Valid range is 1 to 43200 (30 days). `0` is rejected immediately with `PUBNUB_ERR_INVALID_ARGUMENT`, before any network call. There is no default. |
| `channels`Type: `const pubnub_access_resource_permission_t*` | Exact channel permissions. |
| `channel_count`Type: `size_t` | Entries in `channels`. |
| `groups`Type: `const pubnub_access_resource_permission_t*` | Exact channel-group permissions. |
| `group_count`Type: `size_t` | Entries in `groups`. |
| `uuids`Type: `const pubnub_access_resource_permission_t*` | Exact `uuid` (App Context) permissions. |
| `uuid_count`Type: `size_t` | Entries in `uuids`. |
| `channel_patterns`Type: `const pubnub_access_resource_permission_t*` | RegEx pattern channel permissions. |
| `channel_pattern_count`Type: `size_t` | Entries in `channel_patterns`. |
| `group_patterns`Type: `const pubnub_access_resource_permission_t*` | RegEx pattern channel-group permissions. |
| `group_pattern_count`Type: `size_t` | Entries in `group_patterns`. |
| `uuid_patterns`Type: `const pubnub_access_resource_permission_t*` | RegEx pattern `uuid` permissions. |
| `uuid_pattern_count`Type: `size_t` | Entries in `uuid_patterns`. |
| `authorized_uuid`Type: `const char*` | Restricts the token to one client's `uuid`. Left `NULL`, the token can be used by any client that presents it. |
| `meta`Type: `const char*` | A JSON metadata string embedded in the token and readable back after parsing. |
| `timeout_ms`Type: `uint32_t` | Per-request timeout override. When non-zero, takes priority over the context-level `transaction_timeout_ms`. |

`PUBNUB_GRANT_TOKEN_OPTS_INIT` zero-initializes every field, including `ttl`. Set `ttl` explicitly on every call, because the zero it starts at is itself an invalid value.

:::note At least one permission is required
`pubnub_grant_token()` requires a permission on at least one resource or pattern. A call where `channels`, `groups`, `uuids`, `channel_patterns`, `group_patterns`, and `uuid_patterns` are all empty fails immediately with `PUBNUB_ERR_INVALID_ARGUMENT`.
:::

**C-family contract**

* **Header** — `#include <pubnub/features/access.h>`
* **Types** — `pubnub_grant_token_opts_t`, `pubnub_access_resource_permission_t`, `pubnub_access_permission_t`
* **Prerequisite** — a context created or initialized with `subscribe_key`, `publish_key`, and `secret_key` set. See [Identity and keys](https://www.pubnub.com/docs/sdks/c/api-reference/configuration.md#identity-and-keys).
* **Feature flag** — compiled in only when `PUBNUB_ENABLE_PAM` is enabled.
* **Ownership / lifetime** — every string and array field on `pubnub_grant_token_opts_t` is borrowed. The `name` values inside `channels`, `groups`, `uuids`, and the three pattern arrays, plus `authorized_uuid` and `meta`, must all remain valid until `pubnub_grant_token()` returns.
* **Blocking** — starts asynchronous work and returns a `pubnub_future_t` immediately. Validation failures such as a missing or out-of-range `ttl`, no permissions, or missing keys come back as an already-failed future with no network call made.

### Sample code

```c
#include "pubnub/pubnub.h"

#include <stdio.h>

int main(void)
{
    /* 1. Configure and create the client. secret_key is required for
       Access Manager and must never be shipped in client-side code. */
    pubnub_config_t cfg = pubnub_config_defaults();
    cfg.publish_key     = "demo";
    cfg.subscribe_key   = "demo";
    cfg.secret_key      = "demo";
    cfg.user_id         = "admin-user";

    pubnub_context_t* ctx = pubnub_create(&cfg);
    if (NULL == ctx) {
        printf("pubnub_create failed\n");
        return 1;
    }

    /* 2. Build the grant-token request: multiple exact channels plus a pattern. */
    pubnub_access_resource_permission_t channels[] = {
        {"chat.room-1",   PUBNUB_ACCESS_READ | PUBNUB_ACCESS_WRITE},
        {"chat.room-2",   PUBNUB_ACCESS_READ | PUBNUB_ACCESS_WRITE},
        {"notifications", PUBNUB_ACCESS_READ                      },
    };
    pubnub_access_resource_permission_t channel_patterns[] = {
        {"^chat\\.room-.*$", PUBNUB_ACCESS_READ | PUBNUB_ACCESS_WRITE},
    };

    pubnub_grant_token_opts_t opts = PUBNUB_GRANT_TOKEN_OPTS_INIT;
    opts.ttl                       = 60;
    opts.channels                  = channels;
    opts.channel_count             = 3;
    opts.channel_patterns          = channel_patterns;
    opts.channel_pattern_count     = 1;
    opts.authorized_uuid           = "client-user-123";

    pubnub_future_t fut = pubnub_grant_token(ctx, &opts);

    /* 3. Wait for the response. */
    while (!pubnub_future_is_ready(fut)) {
        pubnub_process(ctx);
    }

    /* 4. Read and print the result. */
    const pubnub_res_t status = pubnub_future_status(fut);
    if (PUBNUB_OK == status) {
        pubnub_grant_token_result_t r = pubnub_grant_token_result(fut);
        printf("Token: %.*s\n", (int)r.token.len, r.token.ptr);
    } else {
        pubnub_string_view_t err = pubnub_response_error_message(fut);
        printf("Grant failed: %s (%.*s)\n",
               pubnub_res_str(status),
               (int)err.len,
               err.ptr);
    }

    /* 5. Cleanup. */
    pubnub_future_release(fut);
    pubnub_destroy(ctx);
    return 0;
}
```

### Returns

`pubnub_grant_token()` returns a `pubnub_future_t`. Once `pubnub_future_status()` reports `PUBNUB_OK`, call `pubnub_grant_token_result()` to read the issued token:

| Parameter | Description |
| --- | --- |
| `token`Type: `pubnub_string_view_t` | The issued token. Valid until you call `pubnub_future_release()` on the future that produced it. Read or copy `token.ptr`/`token.len` before releasing. |

### Other examples

#### Grant using an async callback

`pubnub_grant_token()` works the same way with any of the three future-consumption styles. This example uses `pubnub_async()` instead of cooperative polling:

```c
#include "pubnub/pubnub.h"

#include <stdio.h>

static volatile int s_done;

static void on_grant(pubnub_future_t future, pubnub_res_t status, void* user_data)
{
    (void)user_data;

    if (PUBNUB_OK == status) {
        pubnub_grant_token_result_t r = pubnub_grant_token_result(future);
        printf("Token: %.*s\n", (int)r.token.len, r.token.ptr);
    } else {
        pubnub_string_view_t err = pubnub_response_error_message(future);
        printf("Grant failed: %s (%.*s)\n",
               pubnub_res_str(status),
               (int)err.len,
               err.ptr);
    }

    pubnub_future_release(future);
    s_done = 1;
}

int main(void)
{
    pubnub_config_t cfg = pubnub_config_defaults();
    cfg.publish_key     = "demo";
    cfg.subscribe_key   = "demo";
    cfg.secret_key      = "demo";
    cfg.user_id         = "admin-user";

    pubnub_context_t* ctx = pubnub_create(&cfg);
    if (NULL == ctx) {
        printf("pubnub_create failed\n");
        return 1;
    }

    pubnub_access_resource_permission_t channels[] = {
        {"my-channel", PUBNUB_ACCESS_READ | PUBNUB_ACCESS_WRITE},
    };

    pubnub_grant_token_opts_t opts = PUBNUB_GRANT_TOKEN_OPTS_INIT;
    opts.ttl                       = 15;
    opts.channels                  = channels;
    opts.channel_count             = 1;

    pubnub_future_t fut = pubnub_grant_token(ctx, &opts);

    pubnub_res_t rc = pubnub_async(fut, on_grant, NULL);
    if (PUBNUB_OK != rc) {
        printf("pubnub_async failed: %s\n", pubnub_res_str(rc));
        pubnub_future_release(fut);
        pubnub_destroy(ctx);
        return 1;
    }

    while (!s_done) {
        /* on threaded platforms the background thread drives I/O;
           on embedded builds without threads, call pubnub_process(ctx)
           here instead of sleeping */
    }

    pubnub_destroy(ctx);
    return 0;
}
```

### Error responses

Validation failures never reach the network. They come back as an already-failed future:

| Condition | Result |
| --- | --- |
| `opts` is `NULL` | `PUBNUB_ERR_INVALID_ARGUMENT` |
| `ttl` is `0` or exceeds `43200` | `PUBNUB_ERR_INVALID_ARGUMENT` |
| no permission set on any resource or pattern | `PUBNUB_ERR_INVALID_ARGUMENT` |
| the context or its configuration is invalid | `PUBNUB_ERR_INVALID_ARGUMENT` |
| `publish_key` or `secret_key` is not set on the context | `PUBNUB_ERR_INVALID_ARGUMENT` |
| a required allocator/serialization provider is missing | `PUBNUB_ERR_NOT_INITIALIZED` |
| the request queue is full | `PUBNUB_ERR_QUEUE_FULL` |
| an internal allocation fails | `PUBNUB_ERR_OUT_OF_MEMORY` |
| the platform provider's `wall_clock_ms` callback is missing or reports `0` (no RTC / not yet NTP-synchronized), so the PAM request cannot be timestamp-signed | `PUBNUB_ERR_NO_WALL_CLOCK` |

A server-side rejection completes the future with `PUBNUB_ERR_SERVER`. Call `pubnub_response_service_error()` to read the normalized detail. For Access Manager responses specifically, the resulting `pubnub_service_error_t.source` field is populated. It is empty for every other endpoint's error shape. See [Retrieving server error detail](https://www.pubnub.com/docs/sdks/c/status-events.md#retrieving-server-error-detail).

## Revoke token

:::note Requires Access Manager add-on
This function requires that the *Access Manager* add-on, and specifically token revocation, is enabled for your key in the [Admin Portal](https://admin.pubnub.com/). Open your app's keyset and mark the *Revoke v3 Token* checkbox in the *ACCESS MANAGER* section.
:::

`pubnub_revoke_token()` disables a token you previously issued with `pubnub_grant_token()`, invalidating every permission embedded in it. Use it only for tokens with a `ttl` of 30 days or less. For a longer-lived token, contact PubNub support.

### Method(s)

```c
#include <pubnub/features/access.h>

pubnub_future_t pubnub_revoke_token(pubnub_context_t* ctx, const pubnub_revoke_token_opts_t* opts);
```

Revoke options (`pubnub_revoke_token_opts_t`):

| Parameter | Description |
| --- | --- |
| `token` *Type: `const char*` | Borrowed, NUL-terminated. The token to revoke. |
| `timeout_ms`Type: `uint32_t` | Per-request timeout override, same semantics as grant's `timeout_ms`. |

`PUBNUB_REVOKE_TOKEN_OPTS_INIT` zero-initializes both fields. Set `token` explicitly before calling.

**C-family contract**

* **Header** — `#include <pubnub/features/access.h>`
* **Types** — `pubnub_revoke_token_opts_t`
* **Prerequisite** — a context configured with `subscribe_key` and `secret_key` set.
* **Feature flag** — compiled in only when `PUBNUB_ENABLE_PAM` is enabled.
* **Ownership / lifetime** — `token` is borrowed and must remain valid until `pubnub_revoke_token()` returns.
* **Blocking** — starts asynchronous work and returns a `pubnub_future_t` immediately. A missing `token` or missing `secret_key` fails immediately with no network call made.

### Sample code

```c
#include "pubnub/pubnub.h"

#include <stdio.h>

int main(void)
{
    /* 1. Configure and create the client. */
    pubnub_config_t cfg = pubnub_config_defaults();
    cfg.subscribe_key   = "demo";
    cfg.secret_key      = "demo";
    cfg.user_id         = "admin-user";

    pubnub_context_t* ctx = pubnub_create(&cfg);
    if (NULL == ctx) {
        printf("pubnub_create failed\n");
        return 1;
    }

    /* 2. Build and submit the revoke request. */
    pubnub_revoke_token_opts_t opts = PUBNUB_REVOKE_TOKEN_OPTS_INIT;
    opts.token                      = "p0thisIsATokenToRevoke...";

    pubnub_future_t fut = pubnub_revoke_token(ctx, &opts);

    /* 3. Wait for the response. */
    while (!pubnub_future_is_ready(fut)) {
        pubnub_process(ctx);
    }

    /* 4. Check and print the result. */
    const pubnub_res_t status = pubnub_future_status(fut);
    if (PUBNUB_OK == status) {
        printf("Token revoked successfully.\n");
    } else {
        pubnub_string_view_t err = pubnub_response_error_message(fut);
        printf("Revoke failed: %s (%.*s)\n",
               pubnub_res_str(status),
               (int)err.len,
               err.ptr);
    }

    /* 5. Cleanup. */
    pubnub_future_release(fut);
    pubnub_destroy(ctx);
    return 0;
}
```

### Returns

`pubnub_revoke_token()` returns a `pubnub_future_t`. There is no result struct. A successful revoke completes the future with `PUBNUB_OK` and nothing else to read.

### Error responses

| Condition | Result |
| --- | --- |
| `opts` is `NULL` | `PUBNUB_ERR_INVALID_ARGUMENT` |
| `token` is `NULL` or empty | `PUBNUB_ERR_INVALID_ARGUMENT` |
| the context or its configuration is invalid | `PUBNUB_ERR_INVALID_ARGUMENT` |
| `secret_key` is not set on the context | `PUBNUB_ERR_INVALID_ARGUMENT` |

A server-side rejection completes the future with `PUBNUB_ERR_SERVER`. Read the detail the same way as for [Grant token](#grant-token). See [Retrieving server error detail](https://www.pubnub.com/docs/sdks/c/status-events.md#retrieving-server-error-detail).

## Parse token

`pubnub_parse_token()` decodes a token and exposes the permissions embedded in it. Use it for debugging, or to inspect a token received from a grant response or another source before deciding whether to use it.

:::note This call is synchronous and local, not a network request
Unlike `pubnub_grant_token()` and `pubnub_revoke_token()`, `pubnub_parse_token()` returns a `pubnub_res_t` directly, not a `pubnub_future_t`. It decodes the token's base64url-encoded CBOR payload locally and never contacts the server.
:::

### Method(s)

```c
#include <pubnub/features/access.h>

pubnub_res_t pubnub_parse_token(pubnub_context_t* ctx,
                                 const pubnub_parse_token_opts_t* opts,
                                 pubnub_parsed_token_t* out_result);

pubnub_parsed_token_resource_t pubnub_parsed_token_channel_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_group_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_uuid_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_channel_pattern_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_group_pattern_at(pubnub_context_t* ctx, size_t index);
pubnub_parsed_token_resource_t pubnub_parsed_token_uuid_pattern_at(pubnub_context_t* ctx, size_t index);
```

Parse options (`pubnub_parse_token_opts_t`):

| Parameter | Description |
| --- | --- |
| `token` *Type: `const char*` | Borrowed, NUL-terminated. The base64url-encoded token string to decode. |

`PUBNUB_PARSE_TOKEN_OPTS_INIT` zero-initializes the struct. Set `token` explicitly.

**C-family contract**

* **Header** — `#include <pubnub/features/access.h>`
* **Types** — `pubnub_parse_token_opts_t`, `pubnub_parsed_token_t`, `pubnub_parsed_token_resource_t`
* **Prerequisite** — none of the Access Manager keys are required. Parsing does not touch `secret_key` or `publish_key`, and it does not make a request.
* **Feature flag** — compiled in only when `PUBNUB_ENABLE_PAM` is enabled.
* **Ownership / lifetime** — the decoded resource data backing the six accessor functions lives on `ctx`, not on your `out_result`. It stays valid until the next `pubnub_parse_token()` call on the same context, or until `pubnub_destroy()`/`pubnub_deinit()`. The scalar fields you receive by value in `out_result` (`version`, `timestamp`, `ttl`, `authorized_uuid`, and the six `*_count` fields) are yours. Their `*_count` values, though, describe only that parse. Read them and call the accessors before parsing a second token on the same context.
* **Blocking** — synchronous, local only. No network call, no future.

:::warning One parsed token per context
Calling `pubnub_parse_token()` again on the same context replaces the previously decoded data that the six indexed accessor functions read from. Your own `out_result` struct is unaffected, but its `*_count` fields become stale as loop bounds for the accessors once a second parse has happened on that context. Read everything you need, including every accessor call, from the first parse before parsing another token on the same `ctx`.
:::

### Sample code

```c
#include "pubnub/pubnub.h"

#include <stdio.h>

int main(void)
{
    /* 1. Configure and create the client. No secret_key is needed to parse. */
    pubnub_config_t cfg = pubnub_config_defaults();
    cfg.subscribe_key   = "demo";
    cfg.user_id         = "example-parse";

    pubnub_context_t* ctx = pubnub_create(&cfg);
    if (NULL == ctx) {
        printf("pubnub_create failed\n");
        return 1;
    }

    /* 2. Parse the token locally (no network call). */
    /* Token received from a server-side grant or auth flow. */
    const char* token =
        "qEF2AkF0GmFLd-NDdHRsGQWgQ3Jlc6VEY2hhbqFjY2gxGP9DZ3JwoWNj"
        "ZzEY_0N1c3KgQ3NwY6BEdXVpZKFldXVpZDEY_0NwYXSlRGNoYW6gQ2dycK"
        "BDdXNyoENzcGOgRHV1aWShYl4kAURtZXRho2VzY29yZRhkZWNvbG9yY3Jl"
        "ZGZhdXRob3JlcGFuZHVEdXVpZGtteWF1dGh1dWlkMUNzaWdYIP2vlxHik0"
        "EPZwtgYxAW3-LsBaX_WgWdYvtAXpYbKll3";

    pubnub_parsed_token_t     result = {0};
    pubnub_parse_token_opts_t opts   = PUBNUB_PARSE_TOKEN_OPTS_INIT;
    opts.token                       = token;

    pubnub_res_t rc = pubnub_parse_token(ctx, &opts, &result);
    if (PUBNUB_OK != rc) {
        printf("Parse failed: %s\n", pubnub_res_str(rc));
        pubnub_destroy(ctx);
        return 1;
    }

    /* 3. Print the decoded token contents. */
    printf("version=%d ttl=%u min timestamp=%llu\n",
           result.version,
           result.ttl,
           (unsigned long long)result.timestamp);

    if (0 < result.authorized_uuid.len) {
        printf("authorized_uuid=%.*s\n",
               (int)result.authorized_uuid.len,
               result.authorized_uuid.ptr);
    }

    printf("channels=%u groups=%u uuids=%u\n",
           result.channel_count,
           result.group_count,
           result.uuid_count);

    for (size_t i = 0; i < result.channel_count; ++i) {
        pubnub_parsed_token_resource_t r = pubnub_parsed_token_channel_at(ctx, i);
        printf("  chan[%zu]: %.*s perms=0x%x\n",
               i,
               (int)r.name.len,
               r.name.ptr,
               r.permissions);
    }

    for (size_t i = 0; i < result.uuid_pattern_count; ++i) {
        pubnub_parsed_token_resource_t r =
            pubnub_parsed_token_uuid_pattern_at(ctx, i);
        printf("  uuid_pat[%zu]: %.*s perms=0x%x\n",
               i,
               (int)r.name.len,
               r.name.ptr,
               r.permissions);
    }

    /* 4. Cleanup. */
    pubnub_destroy(ctx);
    return 0;
}
```

### Returns

`pubnub_parse_token()` returns `PUBNUB_OK` on success and populates `out_result` (`pubnub_parsed_token_t`):

| Parameter | Description |
| --- | --- |
| `version`Type: `int32_t` | Token format version. |
| `timestamp`Type: `uint64_t` | Token creation time, Unix seconds. |
| `ttl`Type: `uint32_t` | Token time-to-live, in minutes, as embedded in the token. |
| `authorized_uuid`Type: `pubnub_string_view_t` | Empty (`.len == 0`) if the token was granted without an `authorized_uuid` restriction. |
| `channel_count`Type: `uint32_t` | Number of exact channel permissions. This bounds `pubnub_parsed_token_channel_at()`. |
| `group_count`Type: `uint32_t` | Number of exact channel-group permissions. This bounds `pubnub_parsed_token_group_at()`. |
| `uuid_count`Type: `uint32_t` | Number of exact `uuid` permissions. This bounds `pubnub_parsed_token_uuid_at()`. |
| `channel_pattern_count`Type: `uint32_t` | Number of pattern channel permissions. This bounds `pubnub_parsed_token_channel_pattern_at()`. |
| `group_pattern_count`Type: `uint32_t` | Number of pattern channel-group permissions. This bounds `pubnub_parsed_token_group_pattern_at()`. |
| `uuid_pattern_count`Type: `uint32_t` | Number of pattern `uuid` permissions. This bounds `pubnub_parsed_token_uuid_pattern_at()`. |

Each of the six indexed accessor functions returns a `pubnub_parsed_token_resource_t`:

| Parameter | Description |
| --- | --- |
| `name`Type: `pubnub_string_view_t` | The resource name or pattern, aliasing data owned by `ctx`. See the ownership note above. |
| `permissions`Type: `uint32_t` | The permission bits granted to this resource, as `pubnub_access_permission_t` values combined with bitwise OR. |

On failure, `out_result` is zero-initialized rather than left untouched.

### Error responses

| Value | Meaning |
| --- | --- |
| `PUBNUB_OK` | Decoded successfully. `out_result` is populated. |
| `PUBNUB_ERR_INVALID_ARGUMENT` | `opts->token` is `NULL` or empty. |
| `PUBNUB_ERR_SERIALIZATION` | The token is not valid base64url, or does not decode to a valid token structure. |

## Set auth token

A client that receives a token attaches it to its own context with `pubnub_set_auth_token()` so that every subsequent request from that context carries the token. The token can come from your server's `pubnub_grant_token_result_t.token`, or from any other channel you use to deliver tokens. This function is declared in `client.h`, not `access.h`. The full `pubnub_config_t`/runtime-setter story, including `pubnub_get_auth_token()`, is documented in [Runtime updates](https://www.pubnub.com/docs/sdks/c/api-reference/configuration.md#runtime-updates). This section covers only how it applies to a token received from Access Manager.

### Method(s)

```c
#include <pubnub/client.h>

pubnub_res_t pubnub_set_auth_token(pubnub_context_t* ctx, const char* token);
const char*  pubnub_get_auth_token(const pubnub_context_t* ctx);
```

**C-family contract**

* **Header** — `#include <pubnub/client.h>`
* **Prerequisite** — an already created or initialized context.
* **Ownership / lifetime** — on a `pubnub_create`-based context, `pubnub_set_auth_token()` deep-copies `token`. On a `pubnub_init`-based context, it borrows it. `pubnub_get_auth_token()` returns a context-owned pointer, valid until the next `pubnub_set_auth_token()` call or context teardown. Do not free it.
* **Blocking** — synchronous, no I/O.

This snippet is derived from the function declarations in `client.h`. There is no dedicated Access Manager example that exercises it.

### Sample code

```c
#include <pubnub/client.h>

static void apply_granted_token(pubnub_context_t* ctx, const char* token)
{
    pubnub_res_t res = pubnub_set_auth_token(ctx, token);
    if (PUBNUB_OK != res) {
        /* token was rejected -- inspect res with pubnub_res_str() */
        return;
    }

    const char* current = pubnub_get_auth_token(ctx);
    (void)current;
}
```

### Returns

`pubnub_set_auth_token()` returns `PUBNUB_OK` on success, `PUBNUB_ERR_NOT_INITIALIZED` if `ctx` is not initialized, or `PUBNUB_ERR_OUT_OF_MEMORY` if the deep-copy allocation fails (on `pubnub_create`-based contexts). `pubnub_get_auth_token()` returns the context's current `auth_token`, or `NULL` if none is set.

## Terms in this document

* **Access Manager** - A cryptographic, token-based permission administrator that allows you to regulate clients' access to PubNub resources, such as channels, channel groups, and user IDs.
* **Action** - The type of activity (procedure) to execute when a condition is satisfied (for example, sending a message).
* **Billing alert notification** - A means of informing a user that a billing alert has been triggered. Before notifications can happen, a billing alert must be triggered first.
* **Business Object** - A container for data fields and metrics that defines aggregations and data sources.
* **Channel** - A pathway for sending and receiving messages between devices, created automatically when you first use it, that can handle any number of users and messages for different communication needs, like 1-1 text chats, group conversations, and other data streaming.
* **Channel (DataSync)** - A built-in entity class in DataSync that stores channel metadata as a JSON payload. The same channel used for messaging and Presence.
* **Channel pattern** - A way to group and analyze channel data to track performance metrics like message counts and user engagement over time with PubNub Insights.
* **Class** - A versioned type definition (name plus integer version) for entities or relationships in DataSync. Classes carry property definitions that declare which payload fields are validated, filterable, and scoped by projections.
* **Condition** - A requirement that must be satisfied or evaluated to true for an action to be executed. Input in a decision table.
* **Cryptor** - An implementation of a specific cryptographic algorithm used for data encryption/decryption that adheres to a standard interface.
* **Dashboard** - A collection of widgets (charts) that give an overview of the metrics one is evaluating.
* **Data fields** - Data you want Illuminate to track. These can be quantitative (measures), like "Number" or "Timestamp" or qualitative (dimensions) values, like "String" that can be used to categorize and segment data. Data fields can be aggregated and calculated.
* **DataSync** - PubNub's real-time data layer for storing and synchronizing application state as entities and relationships. The successor to App Context.
* **DataSync entity** - A stored server-side object in DataSync with system fields (id, eTag, timestamps) and a free-form JSON payload, typed by exactly one entity class. Not the same as an SDK entity, which is only a local handle.
* **DataSync event** - A real-time change notification (message type 5) published when a DataSync object is created, updated, or deleted. Delivered on the ID channels of the entities the change affects, with a separate channel for each named projection.
* **Decision** - A collection (or decision table) of conditions and actions. When conditions are satisfied, the corresponding actions are triggered as per defined rules.
* **End Customer** - A customer of a PubNub partner. End customers do not have direct access to the Admin Portal. Instead, they interact with PubNub products—such as Illuminate—through the partner’s portal, where PubNub services are embedded. They can create PubNub objects only within this partner-provided environment.
* **Listener** - A function or objectthat reacts to events or messages, like new chat messages or connection updates, letting your app respond in real-time.
* **Mapped/Unmapped** - Whether the data source for a data field has been defined or the action has been configured.
* **MCP Server** - A Model Context Protocol server that coordinates communication and synchronization between AI agents, clients, or services, such as Cursor IDE and Windsurf.
* **Membership** - A relationship in DataSync that links a channel to a user, using the built-in many-to-many Membership class.
* **Message** - A unit of data transmitted between clients or between a client and a server in PubNub, containing information such as text, binary data, or structured data formats like JSON. Messages are sent over channels and can be tracked for delivery and read status.
* **Metric** - What exactly is evaluated using measures and dimensions (collectively called data fields), as well as aggregation functions.
* **Module** - A Functions v1 container that groups related functions for configuration and deployment on an app’s keysets.
* **Origin** - The subdomain used to establish a connection to the PubNub network that allows your application's traffic to appear like it's coming from your own domain.
* **Package** - A Functions v2 container that groups Functions, tracks Revisions, and is deployed to keysets.
* **Partner** - A PubNub customer who resells PubNub products, such as Illuminate, to their own customers. Partners have access to the Admin Portal, enabling them to create and manage PubNub objects for themselves or on behalf of their end customers.
* **Projection** - A named view over an object's payload fields in DataSync, controlling which fields a client can read and write based on its Access Manager token.
* **Publish Key** - A unique identifier that allows your application to send messages to PubNub channels. It's part of your app's credentials and should be kept secure.
* **PubNub** - PubNub is a real-time messaging platform that provides APIs and SDKs for building scalable applications. It handles the complex infrastructure of real-time communication, including: Message delivery and persistence, Presence detection, Access control, Push notifications, File sharing, Serverless processing with Functions and Events & Actions, Analytics and monitoring with BizOps Workspace, AI-powered insights with Illuminate.
* **Push token** - A device identifier issued by a push provider (APNs or FCM) used to register a device for receiving mobile push notifications.
* **Relationship** - A typed link between two entities in DataSync, with its own payload and system fields, typed by a relationship class that declares cardinality.
* **Rule** - A definition (row in a decision table) stating which action should be triggered for which condition.
* **SDK entity** - A local, client-side handle within a PubNub SDK that allows you to perform context-specific operations on one channel, user, or metadata record. Creating one makes no network call and needs no matching server-side record. Not the same as a DataSync entity.
* **Service Integration** - A machine identity that represents a program or service consuming the Admin API, scoped to your account and authenticated using expirable API keys with configurable permissions.
* **Signal** - A non-persistent message limited to 64 bytes designed for high-volume usecases where the the most recent data is relevant, like GPS location updates.
* **Subscribe Key** - A unique identifier that allows your application to receive messages from PubNub channels. It's part of your app's credentials and should be kept secure.
* **Timetoken** - A unique identifier for each message that represents the number of 100-nanosecond intervals since January 1, 1970, for example, 16200000000000000.
* **Trigger details** - A set of predefined criteria for a given billing alert. When met, billing alert notifications are generated.
* **User** - An individual or entity that interacts with a system, application, or service. In PubNub, a user typically refers to someone who sends or receives messages through the platform, identified by a unique user ID or username.
* **User (DataSync)** - A built-in entity class in DataSync that stores user profile data as a JSON payload. The same user that publishes messages and appears in Presence.
* **User ID** - UTF-8 encoded, unique string of up to 92 characters used to identify a single client (end user, device, or server) that connects to PubNub.
* **Vibe Coding** - A way to build applications in an intuitive, relaxed, and improvisational manner, using AI tools and natural language descriptions.

Last updated at: 2026-09-24T12:25:41.000Z
