# API Recipes

{% columns %}
{% column width="50%" %}

### **curl: Authenticate to API using NETOSECRET**

Shell script that takes a NETOSECRET API key, builds a JWT request token, authenticates to the Fusion API, and output the bearer token to use in subsequent API calls.

<a href="/pages/sUsExkwLlOw0PgjFQx9g" class="button primary">Open Recipe</a>
{% endcolumn %}

{% column width="50%" %}
{% code expandable="true" %}

```bash
#!/bin/bash

# Step 1: Check prerequisites
for cmd in jq openssl base64; do
  if ! command -v "$cmd" >/dev/null 2>&1; then
    echo "❌ Required command '$cmd' not found. Please install it and retry." >&2
    exit 1
  fi
done

# Step 2: Retrieve and validate NETOSECRET
if [ -z "$NETOSECRET" ]; then
  echo "❌ Environment variable NETOSECRET is not set."
  echo "To retrieve this value from the Fusion Portal, see:"
  echo "https://docs.netography.com/reference/create-a-netography-api-key"
  exit 1
fi

netosecret=$NETOSECRET

# Step 3: Decode the secret and extract fields using jq
decoded=$(echo "$netosecret" | base64 -d)
appname=$(echo "$decoded" | jq -r .appname)
appkey=$(echo "$decoded" | jq -r .appkey)
shortname=$(echo "$decoded" | jq -r .shortname)
sharedsecret=$(echo "$decoded" | jq -r .sharedsecret)
url=$(echo "$decoded" | jq -r .url)


# Step 4: Create JWT header and payload
header='{"alg":"HS256","typ":"JWT"}'
iat=$(date +%s)
jti=$((RANDOM * RANDOM))
payload=$(jq -nc \
  --arg appname "$appname" \
  --arg appkey "$appkey" \
  --arg shortname "$shortname" \
  --argjson iat "$iat" \
  --argjson jti "$jti" \
  '{iat:$iat,jti:$jti,appname:$appname,appkey:$appkey,shortname:$shortname}')

# Step 5: Define base64url encoding function
base64url() {
  openssl base64 -A | tr '+/' '-_' | tr -d '='
}

# Step 6: Encode header and payload
header64=$(echo -n "$header" | base64url)
payload64=$(echo -n "$payload" | base64url)

# Step 7: Create JWT signature
signature=$(printf "%s.%s" "$header64" "$payload64" \
  | openssl dgst -sha256 -hmac "$sharedsecret" -binary \
  | base64url)
jwt="${header64}.${payload64}.${signature}"

# Step 8: Request bearer token
token_response=$(curl -s -X POST \
  --url "${url}/auth/token" \
  -H "accept: application/json" \
  -H "content-type: application/json" \
  -d "$(jq -nc --arg jwt "$jwt" '{jwt:$jwt}')")

# Step 9: Output bearer token from "access_token" field
access_token=$(echo "$token_response" | jq -r '.access_token // empty')

if [ -n "$access_token" ]; then
  echo "$access_token"
else
  echo "❌ access_token not found in response:"
  echo "$token_response"
fi
```

{% endcode %}
{% endcolumn %}
{% endcolumns %}

### **NetoAPI Python class to create traffic sources in Fusion**

<a href="/pages/FSObPFDNHRbjB8u3Qhyq" class="button primary">Open Recipe</a>

### Retrieve a list of source IP addresses from the blocklist with the API

<a href="/pages/KBFv2kpt3ORmDpyv2DVK" class="button primary">Open Recipe</a>

### Bulk add IP labels (php)

<a href="/pages/0t0NXdemaH5yqGuXZhZ3" class="button primary">Open Recipe</a>

### Authenticate to the API

<a href="/pages/4CqrKva40fjQm2iCVOXx" class="button primary">Open Recipe</a>

### Create a JWT request token

<a href="/pages/yVAvWe597FzKm4DNDhAK" class="button primary">Open Recipe</a>

### Sanitize context label values

<a href="/pages/lXpLCPKX7M6OY7vbE87e" class="button primary">Open Recipe</a>

### netosecret.py - Python class and CLI

<a href="/pages/oGQw4PySq0GlvQIMcZo4" class="button primary">Open Recipe</a>

### netosecret.sh - bash script CLI

<a href="/pages/Izipisohav2LL6I7xuxO" class="button primary">Open Recipe</a>

### Create a Traffic Source in Python

<a href="/pages/OPpAYRlLzkdBCg3PGaGP" class="button primary">Open Recipe</a>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.fusion.vectra.ai/api-recipes/readme.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
