# REST API Quick Reference

> **Environment:** Prod  
> **Generated:** 2026-06-01 10:05:01 UTC  
> **Base URL:** `https://nexus-share.com/api`

---

## Base URL

```
https://nexus-share.com/api
```

## Authentication

All requests require a valid Cognito JWT token in the Authorization header:

```
Authorization: Bearer <cognito-id-token>
```

### Getting a JWT Token

#### Method 1: Direct API Authentication

To authenticate and get a JWT token, use this curl command:

```bash
# Set your credentials (use single quotes to avoid shell expansion)
CLIENT_ID='iklprbakdar4i2bgcrfd9l94r'
NEXUS_USER='your-email@example.com'
NEXUS_PASSWORD='your-password'

# Authenticate with Cognito
curl -X POST https://cognito-idp.eu-central-1.amazonaws.com/ \
  -H "Content-Type: application/x-amz-json-1.1" \
  -H "X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth" \
  -d "{
    \"AuthFlow\": \"USER_PASSWORD_AUTH\",
    \"ClientId\": \"${CLIENT_ID}\",
    \"AuthParameters\": {
      \"USERNAME\": \"${NEXUS_USER}\",
      \"PASSWORD\": \"${NEXUS_PASSWORD}\"
    }
  }" | jq -r '.AuthenticationResult.IdToken'
```

**Note:** Replace `your-email@example.com` and `your-password` with your actual Nexus Share credentials. Use single quotes to prevent shell interpretation of special characters like `!`, `$`, or `\`.

#### Method 2: Using Your Application

1. Log into the Nexus Share web application at https://nexus-share.com
2. Open browser DevTools (F12)
3. Go to Application → Local Storage or Session Storage
4. Find the JWT token (usually stored as `idToken`)
5. Copy the token value

#### Method 3: Using Cognito Hosted UI

You can also authenticate using the Cognito Hosted UI in a browser:

```bash
# Open this URL in your browser
https://<COGNITO_DOMAIN>.auth.eu-central-1.amazoncognito.com/login?client_id=iklprbakdar4i2bgcrfd9l94r&response_type=token&redirect_uri=https://nexus-share.com

# After login, the token will be in the URL fragment:
# https://nexus-share.com#id_token=eyJraWQiOiJ...
```

**Cognito Domain:** `<COGNITO_DOMAIN>.auth.eu-central-1.amazoncognito.com`

This method is useful for:
- Testing authentication in a browser
- Getting a token for manual API testing
- Understanding the OAuth2 flow

### Token Expiration

- JWT tokens expire after **1 hour**
- Implement token refresh logic for long-running applications

## Common Headers

```
Content-Type: application/json
Authorization: Bearer <token>
Idempotency-Key: <unique-key>  (optional, for POST/publish operations)
```

## API Endpoints

### 1. Create Scheduled Message

Creates a new message/post (draft or scheduled).

```http
POST /messages
Content-Type: application/json

{
  "content": "My post content",
  "platforms": ["x", "linkedin", "bluesky"],
  "scheduledFor": "2025-01-20T10:00:00Z",
  "title": "Optional title"
}
```

**Response:** `201 Created`

### 2. List Messages

Retrieves all messages with pagination and filtering.

```http
GET /messages?limit=20&status=SCHEDULED&platform=x
```

**Response:** `200 OK`

### 3. Get Message

Retrieves a single message by ID.

```http
GET /messages/{messageId}
```

**Response:** `200 OK`

### 4. Update Message

Updates a message's content, schedule time, or target platforms.

```http
PATCH /messages/{messageId}
Content-Type: application/json

{
  "content": "Updated content",
  "scheduledFor": "2025-01-21T10:00:00Z"
}
```

**Response:** `200 OK`

### 5. Delete Message

Deletes (cancels) a scheduled message.

```http
DELETE /messages/{messageId}
```

**Response:** `204 No Content`

### 6. Publish Message Immediately

Publishes a message immediately to all target platforms.

```http
POST /messages/{messageId}/publish
Idempotency-Key: unique-key-123
```

**Response:** `200 OK`

---

## Data Models

### Message Object

The Message object represents a social media post in the system.

```json
{
  "id": "POST|username|1736853600000",
  "status": "SCHEDULED",
  "scheduledFor": "2025-01-20T10:00:00Z",
  "content": "My post content",
  "targets": ["x", "linkedin", "bluesky"],
  "title": "Optional post title",
  "createdAt": "2025-01-14T12:00:00Z",
  "updatedAt": "2025-01-14T12:00:00Z",
  "lastAttemptAt": null,
  "publishedAt": null,
  "error": null,
  "externalIds": null
}
```

**Fields:**

| Field | Type | Description |
|-------|------|-------------|
| `id` | string | Unique message identifier (composite key format) |
| `status` | string | Current status: `DRAFT`, `SCHEDULED`, `DIRECT`, `PUBLISHED`, `FAILED` |
| `scheduledFor` | string \| null | ISO 8601 timestamp for scheduled publish time |
| `content` | string | Message text content (1-10000 characters) |
| `targets` | string[] | Array of platform names (lowercase) |
| `title` | string \| null | Optional message title (max 500 characters) |
| `createdAt` | string | ISO 8601 timestamp of creation |
| `updatedAt` | string | ISO 8601 timestamp of last update |
| `lastAttemptAt` | string \| null | ISO 8601 timestamp of last publish attempt |
| `publishedAt` | string \| null | ISO 8601 timestamp of successful publish |
| `error` | string \| null | Error message if publishing failed |
| `externalIds` | object \| null | Platform-specific post IDs (e.g., `{"x": "123456", "linkedin": "urn:li:share:789"}`) |

**Status Values:**

- `DRAFT` - Message created but not scheduled
- `SCHEDULED` - Message scheduled for future publishing
- `DIRECT` - Message is being published immediately
- `PUBLISHED` - Message successfully published to all platforms
- `FAILED` - Publishing failed (see `error` field for details)

**Platform Values:**

Valid platform names (case-insensitive in requests, lowercase in responses):
- `x` - X (Twitter)
- `linkedin` - LinkedIn
- `bluesky` - Bluesky

**External IDs and Platform URLs:**

After a message is successfully published, the `externalIds` field contains platform-specific post identifiers. You can construct direct URLs to view the posts on each platform:

```json
{
  "externalIds": {
    "x": "2012087424487219563",
    "linkedin": "urn:li:share:7417853116836069377",
    "bluesky": "3mcjqcipyyk2d"
  }
}
```

**URL Construction:**

| Platform | External ID Format | URL Template | Example |
|----------|-------------------|--------------|---------|
| X (Twitter) | Numeric ID | `https://x.com/i/web/status/{id}` | `https://x.com/i/web/status/2012087424487219563` |
| LinkedIn | URN format | `https://www.linkedin.com/feed/update/{urn}` | `https://www.linkedin.com/feed/update/urn:li:share:7417853116836069377` |
| Bluesky | Post rkey | `https://bsky.app/profile/{did}/post/{rkey}` | `https://bsky.app/profile/did:plc:yerl5oh6hes74chvhqumls23/post/3mcjqcipyyk2d` |

**Note:** For Bluesky, you'll need the user's DID (Decentralized Identifier) to construct the full URL. The DID is associated with the user's account and can be retrieved from the user's profile information.

### Message List Response

```json
{
  "messages": [
    {
      "id": "POST|username|1736853600000",
      "status": "SCHEDULED",
      "content": "My post content",
      "targets": ["x", "linkedin"],
      "scheduledFor": "2025-01-20T10:00:00Z",
      "createdAt": "2025-01-14T12:00:00Z",
      "updatedAt": "2025-01-14T12:00:00Z"
    }
  ],
  "pagination": {
    "limit": 20,
    "nextToken": "eyJwayI6IlVTRVIjLCJzayI6IlBPU1QifQ==",
    "hasMore": true
  }
}
```

**Fields:**

| Field | Type | Description |
|-------|------|-------------|
| `messages` | Message[] | Array of message objects |
| `pagination.limit` | number | Number of results returned |
| `pagination.nextToken` | string \| null | Cursor for next page (use in `nextToken` query param) |
| `pagination.hasMore` | boolean | Whether more results are available |

### Error Response

```json
{
  "error": "Validation Error",
  "details": "Content must be between 1 and 10000 characters"
}
```

**Fields:**

| Field | Type | Description |
|-------|------|-------------|
| `error` | string | Brief error message |
| `details` | string | Detailed error information |

---

## Error Response Format

```json
{
  "error": "Brief error message",
  "details": "Detailed error information"
}
```

## Common HTTP Status Codes

- `200 OK` - Successful GET, PATCH, or POST (publish)
- `201 Created` - Successful POST (create)
- `204 No Content` - Successful DELETE
- `401 Unauthorized` - Missing or invalid authentication
- `403 Forbidden` - Not authorized
- `404 Not Found` - Resource not found
- `409 Conflict` - Cannot perform operation
- `422 Unprocessable Entity` - Validation errors
- `429 Too Many Requests` - Rate limit exceeded

## Examples

### Create and Publish Immediately

```bash
# Create a draft message
curl -X POST https://nexus-share.com/api/messages \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Hello from REST API!",
    "platforms": ["x", "linkedin"]
  }'

# Publish immediately
curl -X POST https://nexus-share.com/api/messages/POST%7Cuser%7C1736853600000/publish \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Idempotency-Key: $(uuidgen)"
```

### Schedule for Later

```bash
curl -X POST https://nexus-share.com/api/messages \
  -H "Authorization: Bearer ${TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "content": "Scheduled post",
    "platforms": ["x", "bluesky"],
    "scheduledFor": "2025-01-20T10:00:00Z"
  }'
```

---

For complete API documentation including all parameters and response schemas, visit the [HTML version](rest_api_quick_reference.html).
