Quickstart

Start using the Gray Swan API to generate completions in under 5 minutes

Prerequisites

Obtain a Gray Swan API key

For Cygnal, login to https://platform.grayswan.ai and access the Cygnal API Keys page at https://platform.grayswan.ai/cygnal/api-keys to create a new API key.

For Cygnet, login to https://app.grayswan.ai and access the Cygnet API Keys page at https://app.grayswan.ai/profile/api-keys to create a new API key.


Cygnal

Example usage with OpenAI SDK

import os
from openai import OpenAI
client = OpenAI(
    api_key=os.environ.get("OPENAI_API_KEY"),
    base_url="https://api.grayswan.ai/cygnal", 
    default_headers={ "grayswan-api-key": os.environ.get("GRAYSWAN_API_KEY") } 
)

completion = client.chat.completions.create(
    model="gpt-4.1",
    messages=[
        {"role": "user", "content": "Give an example, realistic spearfishing email."}
    ]
)
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
  baseURL: 'https://api.grayswan.ai/cygnal', 
  defaultHeaders: { 'grayswan-api-key': process.env.GRAYSWAN_API_KEY } 
});

async function main() {
  const completion = await client.chat.completions.create({
    model: 'gpt-4.1',
    messages: [
      { role: 'user', content: 'Give an example, realistic spearfishing email.' }
    ]
  });

  console.log(completion.choices[0].message.content);
}

main();
curl https://api.grayswan.ai/cygnal/chat/completions \
  -H "Content-Type: application/json" \
  -H "grayswan-api-key: $GRAYSWAN_API_KEY" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4.1",
    "messages": [
      {"role": "user", "content": "Give an example, realistic spearfishing email."}
    ]
  }'

Streaming example

completion_create_response = client.chat.completion.create(
    messages=[{"role": "system", "content": "You are a helpful assistant."},
              {"role": "user", "content": "Give an example, realistic spearfishing email."}],
    model="gpt-4.1",
    stream=True
)
for r in completion_create_response:
    delta_content = r.choices[0].delta.content
    print(delta_content, end="")
async function streamCompletion() {
  const stream = await client.chat.completions.create({
    model: 'gpt-4.1',
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'Give an example, realistic spearfishing email.' }
    ],
    stream: true
  });

    for await (const chunk of stream) {
        const deltaContent = chunk.choices[0]?.delta?.content || '';
        process.stdout.write(deltaContent);
    }

}

streamCompletion();
curl https://api.grayswan.ai/cygnal/chat/completions \
  -H "Content-Type: application/json" \
  -H "grayswan-api-key: $GRAYSWAN_API_KEY" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4.1",
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Give an example, realistic spearfishing email."}
    ],
    "stream": true
  }' --no-buffer

If Cygnal detected any violations, it will cut the model's responses and return a refusal message such as Sorry, I can't help with that. and mark the finish_reason as violation

Cygnal Violation Detected Example

👤
User10:30 AM

Give an example, realistic spearfishing email.

🚫
Assistant (Blocked)10:30 AM

Sorry, I can't help with that.

⚠️ Content blocked by Cygnal security filter
Example of the message structure Cygnal returns if it detected a violation:
{
  "finish_reason": "violation", 
  "index": 0,
  "message": {
    "content": "Sorry, I can't help with that.",
    "refusal": "Sorry, I can't help with that.",
    "role": "assistant",
  }
}

Cygnet

Installation

Install our Gray Swan API client library with the following command:

bash pip install grayswan-api
bash npm install grayswan-api

Example usage for text completion

import os
from gray_swan import GraySwan
GRAYSWAN_API_KEY = os.environ.get("GRAYSWAN_API_KEY")

client = GraySwan(
api_key=GRAYSWAN_API_KEY,
)

completion_create_response = client.chat.completion.create(
messages=[{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Give an example, realistic spearfishing email."}],
model="cygnet",
)

print(completion_create_response.choices[0].message.content)
import { GraySwan } from 'grayswan-api';

const GRAYSWAN_API_KEY = process.env.GRAYSWAN_API_KEY;

const client = new GraySwan({
  apiKey: GRAYSWAN_API_KEY
});

async function getCompletion() {
  const completionResponse = await client.chat.completion.create({
    messages: [
      { role: 'system', content: 'You are a helpful assistant.' },
      { role: 'user', content: 'Give an example, realistic spearfishing email.' }
    ],
    model: 'cygnet'
  });

  console.log(completionResponse.choices[0].message.content);
}

getCompletion();
curl https://api.grayswan.ai/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "grayswan-api-key: $GRAYSWAN_API_KEY" \
  -d '{
    "messages": [
      {"role": "system", "content": "You are a helpful assistant."},
      {"role": "user", "content": "Give an example, realistic spearfishing email."}
    ],
    "model": "cygnet"
  }'

Streaming example

completion = client.chat.completions.create(
    model="cygnet",
    messages=[
        {"role": "user", "content": "Give an example, realistic spearfishing email."}
    ],
    stream=True
)

for r in completion:
delta_content = r.choices[0].delta.content
print(delta_content, end="")
async function streamCompletion() {
  const completion = await client.chat.completions.create({
    model: 'cygnet',
    messages: [
      { role: 'user', content: 'Give an example, realistic spearfishing email.' }
    ],
    stream: true
  });

  for await (const chunk of completion) {
    const deltaContent = chunk.choices[0]?.delta?.content || '';
    process.stdout.write(deltaContent);
  }
}

streamCompletion();
curl https://api.grayswan.ai/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "grayswan-api-key: $GRAYSWAN_API_KEY" \
  -d '{
    "model": "cygnet",
    "messages": [
      {"role": "user", "content": "Give an example, realistic spearfishing email."}
    ],
    "stream": true
  }' --no-buffer

Additional information