> ## Documentation Index
> Fetch the complete documentation index at: https://developer.worldly.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication Guide

> How to authenticate requests to the Worldly Public API, including how to generate and use the required headers.

# Worldly Public API Authentication Guide

This guide explains how to authenticate requests to the **Worldly Public API**, including how to generate and use the required headers.

***

## Overview

Every Worldly API request requires **two authentication headers**:

| Header                      | Description                                                                                                                                      |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `x-api-key`                 | Your **Developer Account API Key**, created on the Worldly platform.                                                                             |
| `x-developer-request-token` | A dynamic, encrypted token generated using your **Integration Account API Key**, a **current UTC timestamp**, and your **Developer Public Key**. |

> **Note:** The `x-developer-request-token` expires every **12 hours**. You must regenerate it periodically to maintain access.

***

## Prerequisites

Before beginning, ensure you have the following:

* [x] A valid **Developer Account API Key**
* [x] A valid **Integration Account API Key**
* [x] The **Developer Public Key** (`public.pem`) downloaded from the Worldly Platform
  * [x] `Profile` > `Account Settings` > `Integrations`
* [x] OpenSSL installed

  * macOS default path: `/opt/homebrew/bin/openssl`
  * Windows: [Win32 OpenSSL](https://slproweb.com/products/Win32OpenSSL.html)

***

## macOS / Linux Instructions

### 1. Set Environment Variables

```bash theme={null}
export WORLDLY_DEVELOPER_API_KEY='your-developer-api-key'
export WORLDLY_INTEGRATION_API_KEY='your-integration-api-key'
```

#### Check both values are set correctly:

```bash theme={null}
echo ${#WORLDLY_DEVELOPER_API_KEY} ${#WORLDLY_INTEGRATION_API_KEY}
```

Both numbers should be non-zero.

***

### 2. Create the Plaintext Token String

Combine your **Integration Key** and the **current UTC timestamp** with an ampersand (`&`) separator:

```bash theme={null}
printf '%s' "${WORLDLY_INTEGRATION_API_KEY}&$(date -u +'%Y-%m-%dT%H:%M:%SZ')" > secret.txt
```

This file must contain a single line without a trailing newline.

#### Example content:

```
integration-key-value&2025-10-09T22:14:00Z
```

***

### 3. Encrypt Using Your Developer Public Key

Encrypt the string with your **Developer Public Key**, then Base64-encode it.

```bash theme={null}
/opt/homebrew/bin/openssl pkeyutl -encrypt -pubin \
  -inkey /path/to/public.pem \
  -in secret.txt | base64 | tr -d '\r\n' > token.b64
```

#### Save the output token to an environment variable:

```bash theme={null}
export WORLDLY_DEV_REQ_TOKEN=$(cat token.b64)
```

***

### 4. Send an API Request

```bash theme={null}
curl -X GET "https://api-v2.production.higg.org/pic-api/v1/taxonomy-categories" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${WORLDLY_DEVELOPER_API_KEY}" \
  -H "x-developer-request-token: ${WORLDLY_DEV_REQ_TOKEN}"
```

***

### 5. Troubleshooting

| Error or Symptom                                         | Likely Cause                           | Fix                                                                         |
| -------------------------------------------------------- | -------------------------------------- | --------------------------------------------------------------------------- |
| `pkeyutl: Error loading key`                             | Incorrect or missing `public.pem` path | Provide full path and confirm file starts with `-----BEGIN PUBLIC KEY-----` |
| `No such file or directory`                              | Path typo                              | Verify `public.pem` and `secret.txt` exist                                  |
| `curl: (43) A libcurl function was given a bad argument` | Header contains newline or is empty    | Rebuild token using `tr -d '\r\n'`                                          |
| `401 Unauthorized`                                       | Expired or invalid token               | Regenerate with fresh timestamp                                             |
| Empty token                                              | Encryption failed                      | Recheck key path and repeat generation steps                                |

***

### 6. Example: Full Script (macOS/Linux)

```bash theme={null}
#!/bin/bash
export WORLDLY_DEVELOPER_API_KEY='your-developer-api-key'
export WORLDLY_INTEGRATION_API_KEY='your-integration-api-key'
PUBKEY='/path/to/public.pem'

TS="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
WORLDLY_DEV_REQ_TOKEN="$(
  printf '%s' "${WORLDLY_INTEGRATION_API_KEY}&${TS}" \
  | /opt/homebrew/bin/openssl pkeyutl -encrypt -pubin -inkey "$PUBKEY" -in /dev/stdin \
  | base64 | tr -d '\r\n'
)"

curl -v "https://api-v2.production.higg.org/pic-api/v1/products/search" \
  -H "Content-Type: application/json" \
  -H "x-api-key: ${WORLDLY_DEVELOPER_API_KEY}" \
  -H "x-developer-request-token: ${WORLDLY_DEV_REQ_TOKEN}" \
  --data '{"from":0,"size":10}'
```

***

### 7. Token Renewal

* Tokens expire after 12 hours.
* Add this script to a **cron job** or automated workflow that runs twice daily.

***

## Windows / PowerShell Instructions

### 1. Set Environment Variables

```powershell theme={null}
$env:WORLDLY_DEVELOPER_API_KEY = "your-developer-api-key"
$env:WORLDLY_INTEGRATION_API_KEY = "your-integration-api-key"
```

Confirm they're set:

```powershell theme={null}
Write-Host "Developer key length:" $env:WORLDLY_DEVELOPER_API_KEY.Length
Write-Host "Integration key length:" $env:WORLDLY_INTEGRATION_API_KEY.Length
```

***

### 2. Create the Plaintext String

```powershell theme={null}
$timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
$plainText = "$($env:WORLDLY_INTEGRATION_API_KEY)&$timestamp"
Set-Content -Path secret.txt -Value $plainText -NoNewline -Encoding ASCII
```

***

### 3. Encrypt and Encode

```powershell theme={null}
$pubKey = "C:\Path\To\public.pem"

$token = & openssl pkeyutl -encrypt -pubin -inkey $pubKey -in secret.txt |
          openssl base64 -A
$token = $token -replace "`r","" -replace "`n",""
$env:WORLDLY_DEV_REQ_TOKEN = $token
```

Check token length:

```powershell theme={null}
Write-Host "Token length:" $env:WORLDLY_DEV_REQ_TOKEN.Length
```

***

### 4. Send API Request

```powershell theme={null}
$uri = "https://api-v2.production.higg.org/pic-api/v1/products/search"
$body = '{"from":0,"size":10}'
$headers = @{
    "Content-Type" = "application/json"
    "x-api-key" = $env:WORLDLY_DEVELOPER_API_KEY
    "x-developer-request-token" = $env:WORLDLY_DEV_REQ_TOKEN
}

$response = Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $body
$response | ConvertTo-Json -Depth 5
```

***

### 5. Troubleshooting

| Symptom                              | Likely Cause                     | Fix                                   |
| ------------------------------------ | -------------------------------- | ------------------------------------- |
| `pkeyutl: Error loading key`         | Wrong path or invalid public key | Verify full path and file format      |
| `Invoke-RestMethod` connection error | Token contains newline           | Remove `\r` and `\n` using `-replace` |
| 401 Unauthorized                     | Token expired                    | Regenerate with new timestamp         |
| Empty token                          | Encryption failed                | Confirm key path and rerun steps      |

***

### 6. Example: Full PowerShell Script

```powershell theme={null}
# Configuration
$env:WORLDLY_DEVELOPER_API_KEY = "your-developer-api-key"
$env:WORLDLY_INTEGRATION_API_KEY = "your-integration-api-key"
$pubKey = "C:\Path\To\public.pem"

# Token generation
$timestamp = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
$plainText = "$($env:WORLDLY_INTEGRATION_API_KEY)&$timestamp"
Set-Content -Path secret.txt -Value $plainText -NoNewline -Encoding ASCII

$token = & openssl pkeyutl -encrypt -pubin -inkey $pubKey -in secret.txt |
          openssl base64 -A
$token = $token -replace "`r","" -replace "`n",""
$env:WORLDLY_DEV_REQ_TOKEN = $token

# API request
$uri = "https://api-v2.production.higg.org/pic-api/v1/products/search"
$body = '{"from":0,"size":10}'
$headers = @{
    "Content-Type" = "application/json"
    "x-api-key" = $env:WORLDLY_DEVELOPER_API_KEY
    "x-developer-request-token" = $env:WORLDLY_DEV_REQ_TOKEN
}

Invoke-RestMethod -Uri $uri -Method Post -Headers $headers -Body $body | ConvertTo-Json -Depth 5
```

***

### 7. Token Renewal

* Tokens expire every 12 hours.
* Automate regeneration with a **Windows Task Scheduler** job that runs the script twice daily.

***

## Quick Reference

| Parameter           | Example                                          | Notes                                                    |
| ------------------- | ------------------------------------------------ | -------------------------------------------------------- |
| Developer API Key   | `abcd1234xyz...`                                 | Used in `x-api-key`                                      |
| Integration API Key | `efgh5678uvw...`                                 | Used inside the encrypted token                          |
| Timestamp Format    | `2025-10-09T22:14:00Z`                           | UTC ISO 8601                                             |
| Token Lifetime      | 12 hours                                         | Must be refreshed                                        |
| Public Key File     | `/path/to/public.pem` or `C:\Path\To\public.pem` | Must contain `BEGIN PUBLIC KEY` / `END PUBLIC KEY` lines |

***

## Summary

1. Combine your Integration Key and a current UTC timestamp.
2. Encrypt the string with your Developer Public Key using OpenSSL.
3. Base64-encode and remove newlines.
4. Send the token as `x-developer-request-token` along with your `x-api-key`.
5. Regenerate every 12 hours.
