> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://dev.neurologyca.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://dev.neurologyca.com/_mcp/server.

# Getting Started

> Create an API key, authenticate, submit full-analysis jobs, and fetch saved results

## 1. Create an API key

* Log in to the [product dashboard](https://softskills.neurologyca.com).
* Open the [**API Keys** settings tab](https://softskills.neurologyca.com/api-keys).
* Click **Generate API Key**.
* Enter a name and choose an expiry.
* Copy the full key when it is shown. It is only displayed once.

### API key format

* Keys start with `ng_`.
* The preferred auth header is `Authorization: Bearer <token>`.
* The alternative auth header is `X-API-Key: <token>`.

---

## 2. Authenticate requests

**Preferred**

```http
Authorization: Bearer ng_your_full_api_key_here
```

**Alternative**

```http
X-API-Key: ng_your_full_api_key_here
```

If you send `Authorization: ng_xxx...` without the `Bearer ` prefix, the API returns `401 Unauthorized`.

---

## 3. Submit a full-analysis request

### Endpoint

```http
POST /api/v1/full-analysis
```

**Base URL:** `https://softskills-api-b1f382ab39be.herokuapp.com`

### Request type

`multipart/form-data`

### Request fields

| Field           | Type   | Required | Default                                       | Notes                                              |
| --------------- | ------ | -------- | --------------------------------------------- | -------------------------------------------------- |
| `video`         | file   | Yes      | —                                             | MP4, WebM, MOV, AVI, MKV                           |
| `sessionId`     | string | No       | `api_session`                                 | Session identifier                                 |
| `transcript`    | string | No       | `""`                                          | Pre-existing transcript; Deepgram is used if empty |
| `contextPhrase` | string | No       | `professional communication coaching session` | Forwarded to Engine                                |

### Example request

```bash
curl -X POST "https://softskills-api-b1f382ab39be.herokuapp.com/api/v1/full-analysis" \
  -H "Authorization: Bearer ng_your_api_key_here" \
  -F "video=@/path/to/your/video.mp4" \
  -F "sessionId=api_session" \
  -F "contextPhrase=professional communication coaching session"
```

### Response behavior

> **Warning**
>
> **Expect `202 Accepted` in production.** Most real-world videos exceed the synchronous processing window. Always implement the polling flow below — do not assume a `200 OK` will be returned.

| Status         | When                                                     | What to do                                                                |
| -------------- | -------------------------------------------------------- | ------------------------------------------------------------------------- |
| `200 OK`       | Pipeline completed within the sync window (short videos) | Read the result directly from the response body                           |
| `202 Accepted` | Pipeline is still running (most production videos)       | Poll `GET /api/v1/full-analysis/{sessionId}` until `status == "complete"` |

#### Polling flow

```
POST /api/v1/full-analysis
  → 202 { sessionId, pollingUrl, estimatedCompletionAt }

loop every 3–5 seconds:
  GET /api/v1/full-analysis/{sessionId}
    → { status: "processing", progress: { phase, kpnPackagesSent, ... } }

until status == "complete":
  → { status: "complete", result: { video_analysis, biometric_analysis, transcript } }
```

### Example `200`

```json
{
  "sessionId": "api_session",
  "video_analysis": {
    "overall_score": 85,
    "category_scores": {
      "likeability": 8,
      "authenticity": 8,
      "clarity": 9,
      "confidence": 8
    },
    "strengths": ["Clear structure"],
    "areas_for_improvement": ["Add more vocal variety"],
    "filler_word_count": 2,
    "speaking_pace_wpm": 112,
    "labeled_moments": [
      { "timestamp": "0:00", "label": "Engaged", "text": "Thanks for taking the time to meet with me today." }
    ],
    "time_series_scores": [
      { "timestamp": "0:00", "likeability": 65, "authenticity": 90, "clarity": 80, "confidence": 70 }
    ],
    "detailed_feedback": "Clear communication overall with good structure and delivery.",
    "session_summary": "Strong overall delivery with room for more vocal range.",
    "recommendation": "Practice emphasizing key transitions."
  },
  "biometric_analysis": {
    "classification": "Pattern C",
    "coherence_level": "Low",
    "cognitive_effort_level": "High",
    "emotion": "Light-hearted",
    "emotion_valence": 42,
    "emotion_intensity": 64.5,
    "emotion_quadrant": 1,
    "cognitive_summary": "Speaker appears to be working hard to maintain structure.",
    "emotional_summary": "Emotion remains steady and positive.",
    "behavioral_summary": "Delivery is engaged but somewhat effortful.",
    "adaptive_context": "Interview-style communication with moderate pressure.",
    "governance_rationale": "No escalation indicators were detected.",
    "governance_confidence": 0.95,
    "recommended_actions": ["Slow down before transitions"],
    "action_flags": { "flag_1": false, "flag_2": false, "flag_3": false },
    "hci_priorities": {
      "political_performance": 92,
      "comprehension": 85,
      "cognitive_effort": 68,
      "confidence": 45
    },
    "scientific_context": "Pattern suggests elevated effort despite adequate comprehension.",
    "model_version": "0.1.0",
    "latency_ms": 12657.61
  },
  "transcript": "Thanks for taking the time to meet with me today."
}
```

### Example `202`

```json
{
  "sessionId": "api_session",
  "jobId": "123e4567-e89b-12d3-a456-426614174000",
  "pollingUrl": "/api/v1/full-analysis/api_session",
  "reason": "video_too_long",
  "message": "Video accepted for asynchronous processing.",
  "estimatedCompletionAt": "2026-04-13T00:00:00Z",
  "createdAt": "2026-04-13T00:00:00Z"
}
```

---

## 4. Fetch a saved analysis by session

### Endpoint

```http
GET /api/v1/full-analysis/{session_id}
```

### Example request

```bash
curl "https://softskills-api-b1f382ab39be.herokuapp.com/api/v1/full-analysis/session_1744567890123_abc123xyz" \
  -H "Authorization: Bearer ng_your_api_key_here"
```

### Example in-flight response

```json
{
  "status": "processing",
  "sessionId": "session_1744567890123_abc123xyz",
  "userId": "usr_abc123",
  "createdAt": "2026-04-13T20:10:00.000Z",
  "updatedAt": "2026-04-13T20:10:03.000Z",
  "jobId": "3f2a1b4c-1111-2222-3333-444444444444",
  "progress": {
    "phase": "gemini",
    "kpnPackagesSent": 12,
    "kpnPackagesTotal": 30,
    "enginePolls": 4
  },
  "result": null,
  "error": null
}
```

### Example complete response

```json
{
  "status": "complete",
  "sessionId": "session_1744567890123_abc123xyz",
  "userId": "usr_abc123",
  "createdAt": "2026-04-13T20:10:00.000Z",
  "updatedAt": "2026-04-13T20:11:45.000Z",
  "jobId": null,
  "progress": null,
  "error": null,
  "result": {
    "video_analysis": {
      "overall_score": 64,
      "category_scores": {
        "likeability": 6,
        "authenticity": 5,
        "clarity": 7,
        "confidence": 5
      },
      "strengths": ["Strong opener", "Good eye contact"],
      "areas_for_improvement": ["Improve confidence", "Reduce hesitations"],
      "filler_word_count": 2,
      "speaking_pace_wpm": 112,
      "labeled_moments": [
        { "timestamp": "0:00", "label": "Engaged", "text": "Okay, so I'm going to do a test here..." }
      ],
      "time_series_scores": [
        { "timestamp": "0:00", "likeability": 65, "authenticity": 90, "clarity": 80, "confidence": 70 }
      ],
      "detailed_feedback": "Delivery is clear but confidence fluctuates.",
      "session_summary": "Solid structure with noticeable effort and some hesitation.",
      "recommendation": "Slow down and add deliberate pauses before key points."
    },
    "biometric_analysis": {
      "classification": "Pattern C",
      "coherence_level": "Low",
      "cognitive_effort_level": "High",
      "emotion": "Light-hearted",
      "emotion_valence": 42,
      "emotion_intensity": 64.5,
      "emotion_quadrant": 1,
      "cognitive_summary": "Elevated effort with weaker coherence.",
      "emotional_summary": "Affect remains positive despite effort.",
      "behavioral_summary": "Presenter stays engaged but appears strained.",
      "adaptive_context": "The setting suggests a practice communication exercise.",
      "governance_rationale": "No governance issues detected.",
      "governance_confidence": 0.95,
      "recommended_actions": ["Add pauses", "Rehearse difficult transitions"],
      "action_flags": { "flag_1": false, "flag_2": false, "flag_3": false },
      "hci_priorities": {
        "political_performance": 92,
        "comprehension": 85,
        "cognitive_effort": 68,
        "confidence": 45
      },
      "scientific_context": "Pattern suggests substantial effort despite adequate comprehension.",
      "model_version": "0.1.0",
      "latency_ms": 12657.61
    },
    "transcript": "Okay, so I'm going to do a test here..."
  }
}
```

### Example failed response

```json
{
  "status": "failed",
  "sessionId": "session_1744567890123_abc123xyz",
  "userId": "usr_abc123",
  "createdAt": "2026-04-13T20:10:00.000Z",
  "updatedAt": "2026-04-13T20:10:30.000Z",
  "jobId": null,
  "progress": null,
  "result": null,
  "error": "Pipeline error: upstream analysis failed."
}
```

---

## 5. Error responses

| Status | Meaning                                             |
| ------ | --------------------------------------------------- |
| `401`  | Missing or invalid API key                          |
| `404`  | Resource not found or job expired                   |
| `413`  | Video too long for sync without S3/Redis configured |
| `500`  | Internal pipeline error                             |
| `503`  | Redis not configured for async processing           |

Saved analyses may still return `404` if the session does not exist or is no longer available.

---

## Summary

* The surfaced SoftSkills flow is now `POST /api/v1/full-analysis` plus `GET /api/v1/full-analysis/{session_id}`.
* Requests use `multipart/form-data` with a required `video` field.
* Authentication uses `Authorization: Bearer <token>` or `X-API-Key: <token>`.
* Short videos can return `200` immediately; longer runs return `202` and should be fetched later by `sessionId`.