# Quickstart

From an API key to your first answer in five minutes.

## 1. Get an API key

Sign up in the [console](https://sigwise.ai/register), open **API keys** and
create a key. You get two values:

- a **key ID** like `7Hx2Qp9LmZ`, which identifies the key;
- a **signing secret** like `your_secret`, **shown only once**. Keep it on your server.

```bash
export ANALYZE_API_KEY=your_key_id
export ANALYZE_SECRET=your_secret
```

Every account starts with free credit and three signals (`is_scammer`,
`trust_score` and `buyer_intent`), so you can send events right away.

## 2. Set up a client

Requests are authenticated with a short-lived token signed with your secret
(see [Authentication](https://sigwise.ai/docs/guide/authentication.md)). The SDKs sign each request for
you. With plain HTTP, a small shell function does it:

cURL:

```bash
# Signs a JWT with $ANALYZE_SECRET that is valid for five minutes.
b64url() { openssl base64 -A | tr '+/' '-_' | tr -d '='; }
sign() {
  local now=$(date +%s) h p
  h=$(printf '{"alg":"HS256","typ":"JWT"}' | b64url)
  p=$(printf '{"iat":%d,"exp":%d}' "$now" "$((now + 300))" | b64url)
  printf '%s.%s.%s' "$h" "$p" \
    "$(printf '%s.%s' "$h" "$p" | openssl dgst -sha256 -hmac "$ANALYZE_SECRET" -binary | b64url)"
}
API=https://api.sigwise.ai
```

Node.js:

```ts
import { SigWise } from "@sigwise/sdk";

// Reads ANALYZE_API_KEY and ANALYZE_SECRET.
const sigwise = new SigWise();
```

Python:

```python
from sigwise import SigWise

# Reads ANALYZE_API_KEY and ANALYZE_SECRET.
sigwise = SigWise()
```

Go:

```go
import sigwise "github.com/sigwise/sigwise-go"

// Empty values fall back to ANALYZE_API_KEY and ANALYZE_SECRET.
client := sigwise.New("", "")
```

PHP:

```php
// Null arguments fall back to ANALYZE_API_KEY and ANALYZE_SECRET.
$sigwise = new SigWise\Client();
```

> **SDKs**
>
> The SDKs are coming soon to npm, PyPI, the Go module proxy and Packagist. Until
> then, use the cURL tab: the same requests work from any HTTP client.

## 3. Send events

Send what happens to an object. Here, a message from `user-42`:

cURL:

```bash
curl -X POST "$API/v1/objects/user-42/events?api_key=$ANALYZE_API_KEY" \
  -H "Authorization: Bearer $(sign)" -H 'Content-Type: application/json' \
  -d '{"object_type":"user","events":[
        {"type":"event","name":"profile.updated","metadata":{"field":"bio"}},
        {"type":"message","content":"is this still available? can I pay by wire?"}
      ]}'
```

Node.js:

```ts
await sigwise.events.ingest("user-42", {
  object_type: "user",
  events: [
    { type: "event", name: "profile.updated", metadata: { field: "bio" } },
    { type: "message", content: "is this still available? can I pay by wire?" },
  ],
});
```

Python:

```python
sigwise.events.ingest(
    "user-42",
    object_type="user",
    events=[
        {"type": "event", "name": "profile.updated", "metadata": {"field": "bio"}},
        {"type": "message", "content": "is this still available? can I pay by wire?"},
    ],
)
```

Go:

```go
_, err := client.Events.Ingest(ctx, "user-42", &sigwise.IngestRequest{
	ObjectType: sigwise.String("user"),
	Events: []sigwise.EventInput{
		{Type: sigwise.EventTypeEvent, Name: sigwise.String("profile.updated"), Metadata: sigwise.Metadata{"field": "bio"}},
		{Type: sigwise.EventTypeMessage, Content: sigwise.String("is this still available? can I pay by wire?")},
	},
})
```

PHP:

```php
$sigwise->events->ingest('user-42', [
    'object_type' => 'user',
    'events' => [
        ['type' => 'event', 'name' => 'profile.updated', 'metadata' => ['field' => 'bio']],
        ['type' => 'message', 'content' => 'is this still available? can I pay by wire?'],
    ],
]);
```

The API answers `202 Accepted` and schedules an analysis a few seconds later:

```json
{ "object_id": "user-42", "accepted": 2, "analysis_status": "scheduled", "analysis_delay_ms": 5000 }
```

## 4. Read the answers

cURL:

```bash
curl "$API/v1/objects/user-42?api_key=$ANALYZE_API_KEY" -H "Authorization: Bearer $(sign)"
```

Node.js:

```ts
const object = await sigwise.objects.get("user-42");
console.log(object.analysis, object.pending);
```

Python:

```python
obj = sigwise.objects.get("user-42")
print(obj["analysis"], obj["pending"])
```

Go:

```go
obj, err := client.Objects.Get(ctx, "user-42")
```

PHP:

```php
$object = $sigwise->objects->get('user-42');
```

`analysis` holds the latest answer for each signal; `pending` lists the
signals that have no answer yet. Right after ingesting, everything is pending
until the analysis runs.

## 5. Ask your own question

Add a signal with `PUT /v1/signals/{key}`. It is used from the next analysis
on:

cURL:

```bash
curl -X PUT "$API/v1/signals/wants_refund?api_key=$ANALYZE_API_KEY" \
  -H "Authorization: Bearer $(sign)" -H 'Content-Type: application/json' \
  -d '{"type":"noul","instructions":"Is this customer asking for a refund?",
       "criteria":{"true":"asks for money back","false":"anything else"}}'
```

Node.js:

```ts
await sigwise.signals.upsert("wants_refund", {
  type: "noul",
  instructions: "Is this customer asking for a refund?",
  criteria: { true: "asks for money back", false: "anything else" },
});
```

Python:

```python
sigwise.signals.upsert(
    "wants_refund",
    type="noul",
    instructions="Is this customer asking for a refund?",
    criteria={"true": "asks for money back", "false": "anything else"},
)
```

Go:

```go
_, err := client.Signals.Upsert(ctx, "wants_refund", &sigwise.SignalInput{
	Type:         sigwise.SignalTypeNoul,
	Instructions: "Is this customer asking for a refund?",
	Criteria:     map[string]string{"true": "asks for money back", "false": "anything else"},
})
```

PHP:

```php
$sigwise->signals->upsert('wants_refund', [
    'type' => 'noul',
    'instructions' => 'Is this customer asking for a refund?',
    'criteria' => ['true' => 'asks for money back', 'false' => 'anything else'],
]);
```

Existing objects are not re-analyzed automatically, since each analysis is
billed. To answer the new signal for them, start a [backfill](https://sigwise.ai/docs/guides/backfills.md).

## Next

- [Signals](https://sigwise.ai/docs/guide/signals.md): the three types and how to write criteria.
- [Direct moderation](https://sigwise.ai/docs/guides/moderation.md): score content before publishing it.
- [Webhooks](https://sigwise.ai/docs/guides/webhooks.md): stop polling and get answers pushed to you.
