---
source_url: https://www.pubnub.com/docs/sdks/freertos/api-reference/configuration
title: Configuration API for FreeRTOS SDK
updated_at: 2026-06-22T14:39:35.629Z
sdk_name: PubNub FreeRTOS SDK
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Configuration API for FreeRTOS SDK

PubNub FreeRTOS SDK

FreeRTOS complete API reference for building real-time applications on PubNub, including basic usage and sample code.

## Configuration

This page describes the preprocessor definitions (macros) that configure C‑Core. They live in the `pubnub_config.h` header file. The header file differs by platform. Some definitions that do not apply to a platform may be omitted.

Any definitions that you find in `pubnub_config.h` and that are not listed here should not be changed.

### PUBNUB_CTX_MAX: maximum number of contexts

Maximum number of PubNub contexts that can be used at the same time. It is used only if the contexts are statically allocated. The default on hosted platforms (POSIX, Windows...) is to use dynamically allocated contexts, so this is ignored. This is selected by linking in the "context allocation module" that you wish to use (static or dynamic).

A context is used to publish messages or subscribe to (get) them.

Each context can consume (for our purposes) a significant amount of memory, so don't put some number that is never going to be achieved here.

A typical configuration may consist of a single PubNub context for channel subscription and another PubNub context that will periodically publish messages about device status (with timeout lower than message generation frequency). This only needs two contexts.

Another typical setup may have a single subscription context and maintain a pool of contexts for each publish call triggered by an external event (for example, a button push). This would need N+1 contexts, N being the number of external events.

Of course, there is nothing wrong with having just one context, but you can't publish and subscribe at the same time on the same context. This isn't as bad as it sounds, but may be a source of headaches (lost messages, etc).

### PUBNUB_BUF_MAXLEN: size of HTTP buffer

Size of the HTTP buffer, in bytes. It heavily impacts the context memory size and sets the upper bound on the URL‑encoded message size. For messages up to 2 KB, set about `2500` for `PUBNUB_BUF_MAXLEN`. For larger messages, increase the buffer.

You can set this via compiler options. If not, change the default value in the header.

### PUBNUB_DYNAMIC_REPLY_BUFFER: use dynamic reply buffer

Set to `false` (0) to use a static buffer and then set its size via `PUBNUB_REPLY_MAXLEN`. Set to `true` (anything !=0) to use a dynamic buffer, that is, dynamically try to allocate as much memory as needed for the buffer.

Default on hosted platforms (Windows, POSIX...) is to use a dynamic reply buffer. Be aware that this can involve large amounts of data (megabytes). If memory is constrained, prefer a static reply buffer. If the reply exceeds the size of your statically allocated buffer, the transaction will fail. Choose the option that best suits your application.

### PUBNUB_REPLY_MAXLEN: reply static length

This is only significant if `PUBNUB_DYNAMIC_REPLY_BUFFER` is `true`. In that case it defines the size, in octets, of the reply buffer. It will hold the whole (HTTP) body of the reply, not the (HTTP) headers.

Replies of API calls longer than this will be discarded and an error will be reported. Specifically, this may cause lost messages returned by subscribe if too many too large messages got queued on the PubNub server.

### PUBNUB_ORIGIN: the DNS hostname of PubNub

This is the DNS hostname for the PubNub network. In most cases, do not change it. If enabled (see `PUBNUB_ORIGIN_SETTABLE`), you can set `origin` at runtime.

But, in the case that you do need to change it at compile time, but not at runtime and want to save some RAM in the context, it's OK to change this macro.

### PUBNUB_ORIGIN_SETTABLE: is origin settable at runtime

If `true (!=0)`, the origin can be changed at runtime. This adds a small memory cost.

If `false (==0)`, the origin cannot be changed at runtime. Use this to reduce RAM usage.

### PUBNUB_DEFAULT_TRANSACTION_TIMER: duration of transaction timeout

Duration of the transaction timeout set during context initialization, in milliseconds. Timeout duration in the context can be changed by the user after initialization (at runtime).

This is used only if timer support is enabled (default on hosted platforms).

### PUBNUB_CALLBACK_THREAD_STACK_SIZE_KB: size of the PubNub thread

Stack size (in kilobytes) for the polling thread when using the callback interface. Smaller values save memory, but avoid less than 64 KB.

Set `0` to use the default. Ignored by the sync interface.

### PUBNUB_PROXY_API: enable proxy support

Set `true (!=0)` to enable proxy support (default on hosted platforms). Configure host, port, and protocol with the C‑Core APIs.

Set `false (==0)` to disable proxy support and reduce code size.

Depending on your build, you may also need to exclude proxy modules from compilation and linking. See the sample makefiles.

### PUBNUB_MAX_PROXY_HOSTNAME_LENGTH: max length of proxy hostname

Maximum length (characters) of the proxy host name stored in the context. Set this to fit your proxy names. One host name is stored per context.

### PUBNUB_ONLY_PUBSUB: use only publish&subscribe

Set `true (!=0)` to support only Publish and Subscribe. Default is `false` on hosted platforms.

This reduces code size if you do not need other transactions.

If you compile modules not needed in this mode, the build may warn. Many linkers drop unused modules automatically, but behavior depends on your toolchain.

You can set this via compiler options or edit the header default.

## Initialization

There is no installation of this SDK. Just clone the Git(hub) repo, or download a ZIP or tarball of a release from [https://github.com/pubnub/c-core/releases](https://github.com/pubnub/c-core/releases). It has the code and example Visual Studio solutions to get you started, using the FreeRTOS Windows simulator. Please take a look at [README.md](https://github.com/pubnub/c-core/tree/master/freertos#pubnub-c-core-for-the-freertostcp) in the root of the repo for general info about the repo layout & contents.

Solution for FreeRTOS+TCP (without SSL/TLS support) is at [/freertos/samples/Pubnub.sln](https://github.com/pubnub/c-core/tree/master/freertos) in the repo. Also, check [/freertos/README.md](https://github.com/pubnub/c-core/tree/master/freertos#pubnub-c-core-for-the-freertostcp) for info on how to build on Windows. Solution should work with Visual Studio 2010 or newer.

Use the solution and its projects as a starting point in your own projects (whether they are based on Visual Studio or some other build tool / system or IDE).

#### FreeRTOS+TCP remarks

Pubnub SDK for FreeRTOS+TCP doesn't initialize the TCP/IP stack. It is expected that the user will initialize TCP/IP stack before the first call to any Pubnub SDK function. Other than that, there are no other special requirements for the usage of this SDK. You don't have to create a special task to use the SDK, or call some function in your task before you use the SDK, or anything like that.

FreeRTOS and its FreeRTOS+TCP stack are configurable. Pubnub SDK will adapt to the configuration that the user selects as much as possible, but, not all configurations are supported. Foremost, since TCP is required, you can't only build UDP.

#### Memory allocation

This client uses dynamic memory allocation for the PubNub contexts, but the usage is the same as for any other Pubnub C client - always use `pubnub_alloc()` to create a context (and check its return value) and always use `pubnub_free()` to dispose of a context.

##### Code sample

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
#include "pubnub_alloc.h"

int memory_allocation_sample()
{
    pubnub_t *ctx = pubnub_alloc();
    if (NULL == ctx) {
        return -1;
    }
    /* Do something with ctx...
        and then: */
    pubnub_free(ctx);
    return 0
}
```

#### Timers

There is one timer: the total transaction timer. It starts when a transaction starts and stops when it finishes. If it expires, the transaction is cancelled locally. If a publish already reached the server, cancellation does not roll it back.

If the transaction timer expires, the outcome is `timeout`.

The actual duration can exceed what you set due to platform factors, but it is usually close.

Set the timer after initializing the context and before starting transactions. The setting applies to all transaction types.

#### Thread safety

C-core supports thread-safe operation, though, for performance, you may think about not using it. To use thread-safety support, define the preprocessor symbol `PUBNUB_THREADSAFE` (just define it, the value does not matter).

##### Thread-safe usage

Thread safety is internal. Just because you can access the PubNub context through the PubNub C-core SDK API from different threads safely, doesn't mean you're `off the hook` for your own data that is related to a context. For example, if you're using the callback interface and signalling an event from it to other (`worker`) thread(s), you have to synchronise that data transfer yourself.

If you compiled thread-safety support in, you are free to access the same context from different threads, pretty much in any way you wish. However, there are some advised guidelines you should follow:

* If you're using the sync blocking interface, threads that come to wait on the context may wait a long time, so try to avoid it (also, re-think your whole need for a thread-safe C-core).
* If you're using the sync non-blocking interface by calling `pubnub_await`, things are pretty much the same as for sync blocking interface.
* If you're using the sync non-blocking interface and avoid `pubnub_await`, waiting threads will not block so long, but, pretty much the only useful thing you can do is cancel a transaction from another thread.
* Using the sync interface, it's perfectly fine to call `pubnub_await` or `pubnub_last_result` in different threads, but, you probably shouldn't do that, as it will make debugging harder.
* If you're using the callback interface, it's perfectly fine to call Functions from your callback, but, you should avoid doing that, except for some helper functions. Following this guideline will make your debugging, thus life, a lot easier.

##### Thread-unsafe usage

If you compile without thread-safety support, obviously, you will have an SDK which is not thread safe - that is, it is not safe to use a single context from more than one thread at the same time. So, if you're using such SDK configuration in a multithreaded code, which, on FreeRTOS, you likely are, then:

1. If at all possible, use a single context from only one thread - the one that created it.
2. If 1. is not possible, provide some synchronization yourself, for example, using pthread condition variables, or just mutexes, or some higher abstraction, like message queues.
3. As a special case, if you're using the callback interface, you can start a transaction in one thread and then don't touch the context from that thread any more - use it only in the callback. This is safe.

:::warning Context usage
Keep in mind that it is perfectly safe to use different contexts from different threads at the same time. To each (thread) its own (context).
:::

#### Calling patterns

This SDK provides `sync` and `callback` (notification) interfaces for retrieving the outcome of a Pubnub request/transaction/operation.

##### Sync

The `sync` interface in general works like this:

1. Start a transaction (say, publish - using `pubnub_publish()`).
2. Either `pubnub_await()` the outcome, or use your own loop in which you check `if (PNR_STARTED != pubnub_last_result())`.
3. Handle the outcome as you wish.

This is illustrated in the `Hello World` example below (which is the same for any platform that supports `sync` interface).

##### Callback

The `callback` interface is somewhat more flexible, uses less CPU resources, but is, in general, a little harder to use. One way to use it is to emulate the `sync` interface:

1. Create a `callback` function (`my_callback`) per the prototype required by `pubnub_register_callback()`.
2. In `my_callback()`, use a condition variable to signal that outcome was received.
3. Set the `callback` via `pubnub_register_callbac()`.
4. Start a transaction (say, publish - using `pubnub_publish()`).
5. Wait on the condition variable (the same one used in `my_callback`).
6. Handle the outcome as you wish.

This is illustrated in the `Hello World` example below, using pthreads condition variable. Obviously, on platforms that don't support pthreads you will use some similar API (for example, SetEvent/WaitForSingleObject on Windows).

There are other ways to use the callback interface, like the `state machine` or similar, where the callback will handle the outcome of a transaction but will also start the next Pubnub transaction, or do other stuff that it needs to do. This is application-specific, so we don't provide an example here.

### Description

This function is used for initializing the PubNub Client API context. This function must be called before attempting to utilize any API functionality in order to establish account level credentials such as `publish_key` and `subscribe_key`.

### Method(s)

To `Initialize` PubNub you can use the following method(s) in the FreeRTOS SDK:

```c
void pubnub_init (pubnub_t *p, const char *publish_key, const char *subscribe_key)
```

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| p | pubnub_t* | Yes |  | Pointer to the Context to initialize (use `pubnub_alloc()` to obtain it) |
| publish_key | char | Yes |  | Pointer to the `string` of the key to use when publishing messages. |
| subscribe_key | char | Yes |  | Pointer to the `string` of the key to use when subscribing to messages |

### Sample code

#### Initialize the PubNub client API

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_t *ctx = pubnub_alloc();
if (NULL == ctx) {
    return -1;
}
pubnub_init(ctx, "demo", "demo");
pubnub_set_uuid(ctx, "myUniqueUUID");
pubnub_set_ssl_options(ctx, true, true, true);
```

### Returns

It returns the PubNub instance for invoking PubNub APIs like pubnub_publish(), `pubnub_subscribe()`, `pubnub_history()`, or `pubnub_here_now()`.

### Other examples

#### Initialize the client

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_init(ctx, /*publish key*/"demo", /*subscribe key*/"demo");
pubnub_set_uuid(ctx, "myUniqueUUID");
```

#### Initialization for a Read-Only client

In the case where a client will only read messages and never publish to a channel, you can simply omit the `publish_key` when initializing the client:

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_init(ctx, "", "demo");
```

#### Use a custom UUID

Set a custom `UUID` to identify your users.

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_t *pn = pubnub_alloc();
pubnub_init(pn, "myPublishKey", "mySubscribeKey");
pubnub_set_uuid(pn, "myUniqueUUID");
```

#### Initializing with SSL enabled

This examples demonstrates how to enable PubNub Transport Layer Encryption with `SSL`. Just initialize the client with second set to `true`. The hard work is done, now the PubNub API takes care of the rest. Just subscribe and publish as usual and you are good to go.

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_t *ctx = pubnub_alloc();
if (NULL == ctx) {
    return -1;
}
pubnub_init(ctx, "demo", "demo");
pubnub_set_uuid(ctx, "myUniqueUUID");
pubnub_set_ssl_options(ctx, true, true, true);
```

## UUID

These functions are used to set/get a user ID on the fly.

### Method(s)

To set/get `UUID` you can use the following method(s) in FreeRTOS SDK:

```c
void pubnub_set_uuid (pubnub_t *p, const char *uuid)
```

| Parameter | Description |
| --- | --- |
| `p` *Type: pubnub_t* | Pointer to PubNub context |
| `uuid` *Type: const char* | Pointer to `uuid` `string` |

```c
char const *pubnub_uuid_get(pubnub_t *p)
```

| Parameter | Description |
| --- | --- |
| `p` *Type: pubnub_t* | Pointer to pubnub client context. |

After `pubnub_init()`, it will return NULL until you change it to non-NULL via `pubnub_set_uuid()`.

### Sample code

#### Set UUID

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_t *ctx = pubnub_alloc();
if (NULL == ctx) {
    puts("Couldn't allocate a Pubnub context");
    return -1;
}
pubnub_init(ctx, "myPublishKey", "mySubscribeKey");
pubnub_set_uuid(ctx, "myUniqueUUID");
```

#### Get UUID

```c
printf("UUID is %s", pubnub_uuid_get(ctx));
```

### Returns

Get UUID returns the following output:

| Type | Description |
| --- | --- |
| `char const*` | `UUID` for context. Null if not set. |

### Other examples

#### Initializing with a custom uuid

:::note Required UUID
Always set the `UUID` to uniquely identify the user or device that connects to PubNub. This `UUID` should be persisted, and should remain unchanged for the lifetime of the user or the device. If you don't set the `UUID`, you won't be able to connect to PubNub.
:::

```c
pubnub_t *ctx = pubnub_alloc();
if (NULL == ctx) {
    puts("Couldn't allocate a Pubnub context");
    return -1;
}

struct Pubnub_UUID uuid;
char random_uuid;
if (0 == pubnub_generate_uuid_v4_random(&uuid)) {
    random_uuid = pubnub_uuid_to_string(&uuid).uuid;
    pubnub_init(ctx, "myPublishKey", "mySubscribeKey");
    pubnub_set_uuid(ctx, random_uuid);
}

pubnub_free(ctx);
```

## Authentication key

Setter and getter for users auth key.

### Method(s)

```c
pubnub_set_auth(pubnub_t* p, const char* auth)
```

| Parameter | Description |
| --- | --- |
| `p` *Type: pubnub_t* | Pointer to pubnub client context |
| `auth`Type: const char* | Pointer to `auth` `string`. NULL to unset |

```c
char const *pubnub_auth_get(pubnub_t *p)
```

| Parameter | Description |
| --- | --- |
| `p` *Type: pubnub_t* | Pointer to pubnub client context |

### Sample code

#### Set auth key

```c
pubnub_t *ctx = pubnub_alloc();
if (NULL == ctx) {
    return -1;
}
pubnub_init(ctx, "demo", "demo");
pubnub_set_auth(ctx, "my_new_authkey");
```

#### Get auth key

```c
pubnub_t *ctx = pubnub_alloc();
if (NULL == ctx) {
    puts("Couldn't allocate a Pubnub context");
    return -1;
}
pubnub_init(ctx, "demo", "demo");
pubnub_set_auth(ctx, "my_auth_key");
printf("Auth Key is %s", pubnub_auth_get(ctx));
```

### Returns

`Get Auth key` returns the `current authentication key`.

## Origin

Sets the origin (DNS host) for context `p`. If runtime origin is disabled, the call fails. NULL resets the origin to the default.

### Method

To set the origin for a Pubnub context use:

```c
int pubnub_origin_set(pubnub_t *p, char const *origin)
```

| Parameter | Description |
| --- | --- |
| `p` *Type: pubnub_t * | Pubnub context to set `origin` for |
| `Origin`Type: char const* | The `origin` to use for context `p`. If NULL, the default `origin` will be set. To request a custom domain, contact support and follow the [request process](https://www.pubnub.com/docs/general/setup/data-security#request-process). |

### Sample code

To set the origin to the European data center explicitly:

```c
pubnub_origin_set(pn, "ps.pndsn.com");
```

### Returns

| Type | Description |
| --- | --- |
| `int` | 0: success, -1: fail |

## Terms in this document

* **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.
* **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.