---
title: "Community Events API"
description: "Community events API — create, manage, and track developer meetups and hackathons"
canonical: "https://docs.ainative.studio/docs/community/events"
last-updated: "2026-10-22T17:48:46.689Z"
---

# Community Events API

Source: https://docs.ainative.studio/docs/community/events

> Community events API — create, manage, and track developer meetups and hackathons

## Community Events API

The Community Events API covers the full lifecycle of community events: creating, managing, RSVPing, browsing, and exporting. All data is scoped to your tenant.

**Base path:** `https://api.ainative.studio/api/v1/community-events`

**Authentication:** All endpoints require `Authorization: Bearer <your_api_key>` unless noted otherwise.

---

## Event CRUD

### Create an event

<span className="badge badge--post">POST</span> `/api/v1/community-events/`

Create a new community event. The authenticated user becomes the event creator.

#### Request body

```json
{
  "title": "AI Builders Meetup — May 2026",
  "description": "Monthly meetup for AI builders in San Francisco.",
  "start_time": "2026-05-20T18:00:00Z",
  "end_time": "2026-05-20T21:00:00Z",
  "location": "Hack the Lab, 123 Market St, San Francisco",
  "event_type": "in_person",
  "capacity": 80,
  "group_id": null
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| `title` | `string` | Yes | Event title |
| `description` | `string` | No | Event description |
| `start_time` | `datetime` (ISO 8601) | Yes | Event start time (UTC) |
| `end_time` | `datetime` (ISO 8601) | No | Event end time (UTC) |
| `location` | `string` | No | Physical address or meeting link |
| `event_type` | `string` | No | `virtual`, `in_person`, or `hybrid` |
| `capacity` | `integer` | No | Maximum number of attendees (null = unlimited) |
| `group_id` | `string` (UUID) | No | Attach event to a group |

#### Response `201 Created`

```json
{
  "id": "abc12345-0000-0000-0000-000000000001",
  "title": "AI Builders Meetup — May 2026",
  "description": "Monthly meetup for AI builders in San Francisco.",
  "start_time": "2026-05-20T18:00:00Z",
  "end_time": "2026-05-20T21:00:00Z",
  "location": "Hack the Lab, 123 Market St, San Francisco",
  "event_type": "in_person",
  "capacity": 80,
  "status": "scheduled",
  "creator_id": "550e8400-e29b-41d4-a716-446655440000",
  "tenant_id": "tenant-uuid-here",
  "group_id": null,
  "created_at": "2026-04-25T14:00:00Z",
  "updated_at": "2026-04-25T14:00:00Z"
}
```

#### Errors

| Code | Reason |
|---|---|
| `400` | Invalid dates, missing required fields, or user has no tenant |

#### Example

```bash
curl -X POST https://api.ainative.studio/api/v1/community-events/ \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "AI Builders Meetup — May 2026",
    "start_time": "2026-05-20T18:00:00Z",
    "event_type": "in_person",
    "capacity": 80
  }'
```

```python
import requests

resp = requests.post(
    "https://api.ainative.studio/api/v1/community-events/",
    headers={"Authorization": f"Bearer {api_key}"},
    json={
        "title": "AI Builders Meetup — May 2026",
        "start_time": "2026-05-20T18:00:00Z",
        "event_type": "in_person",
        "capacity": 80,
    }
)
event = resp.json()
print(f"Created event: {event['id']}")
```

---

### List events

<span className="badge badge--get">GET</span> `/api/v1/community-events/`

List community events with optional filtering and pagination.

#### Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `filter_type` | `string` | — | `upcoming`, `past`, or `my_events` |
| `group_id` | `string` (UUID) | — | Filter by group ID |
| `limit` | `integer` | `50` | Max results (1–100) |
| `offset` | `integer` | `0` | Pagination offset |

#### Response `200 OK`

```json
{
  "total": 23,
  "offset": 0,
  "limit": 50,
  "has_more": false,
  "events": [
    {
      "id": "abc12345-0000-0000-0000-000000000001",
      "title": "AI Builders Meetup — May 2026",
      "start_time": "2026-05-20T18:00:00Z",
      "event_type": "in_person",
      "status": "scheduled",
      "capacity": 80
    }
  ]
}
```

---

### Get event details

<span className="badge badge--get">GET</span> `/api/v1/community-events/{event_id}`

Get full details for a specific event.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Response `200 OK`

Returns a full `EventResponse` object (same shape as the create response).

#### Errors

| Code | Reason |
|---|---|
| `404` | Event not found or outside your tenant |

---

### Update an event

<span className="badge badge--patch">PATCH</span> `/api/v1/community-events/{event_id}`

Update an existing event. Only the creator can update their event.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Request body

Send only the fields you want to update:

```json
{
  "title": "AI Builders Meetup — May 2026 (Updated)",
  "capacity": 100
}
```

#### Response `200 OK`

Returns the updated `EventResponse` object.

#### Errors

| Code | Reason |
|---|---|
| `403` | Authenticated user is not the event creator |
| `404` | Event not found |

---

### Delete (cancel) an event

<span className="badge badge--delete">DELETE</span> `/api/v1/community-events/{event_id}`

Cancel an event. Only the creator can delete their event. This marks the event as cancelled rather than permanently deleting it.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Response `204 No Content`

#### Errors

| Code | Reason |
|---|---|
| `403` | Authenticated user is not the event creator |
| `404` | Event not found |

---

## RSVP operations

### RSVP to an event

<span className="badge badge--post">POST</span> `/api/v1/community-events/{event_id}/rsvp`

Create or update your RSVP for an event.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Request body

```json
{
  "status": "going",
  "response_message": "Looking forward to it!"
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| `status` | `string` | Yes | `going`, `interested`, or `not_going` |
| `response_message` | `string` | No | Optional message to the organizer |

#### Response `201 Created`

```json
{
  "id": "rsvp-uuid-here",
  "event_id": "abc12345-0000-0000-0000-000000000001",
  "user_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "going",
  "response_message": "Looking forward to it!",
  "created_at": "2026-04-25T14:30:00Z"
}
```

#### Errors

| Code | Reason |
|---|---|
| `400` | Event is at capacity (for `going` status), or event is cancelled |
| `404` | Event not found |

#### Example

```bash
curl -X POST https://api.ainative.studio/api/v1/community-events/abc12345-0000-0000-0000-000000000001/rsvp \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"status": "going"}'
```

```python
resp = requests.post(
    "https://api.ainative.studio/api/v1/community-events/abc12345-0000-0000-0000-000000000001/rsvp",
    headers={"Authorization": f"Bearer {api_key}"},
    json={"status": "going", "response_message": "Looking forward to it!"}
)
```

---

### Update an RSVP

<span className="badge badge--patch">PATCH</span> `/api/v1/community-events/rsvps/{rsvp_id}`

Change your RSVP status. Users can only update their own RSVPs.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `rsvp_id` | `string` (UUID) | Yes | RSVP ID |

#### Request body

```json
{
  "status": "not_going"
}
```

#### Response `200 OK`

Returns the updated `RSVPResponse` object.

#### Errors

| Code | Reason |
|---|---|
| `400` | Event is at capacity when changing to `going` |
| `403` | You do not own this RSVP |
| `404` | RSVP not found |

---

## Attendee and RSVP lists

### Get event attendees

<span className="badge badge--get">GET</span> `/api/v1/community-events/{event_id}/attendees`

Get attendees for an event with optional RSVP status filter.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `status_filter` | `string` | — | Filter by RSVP status: `going`, `interested`, or `not_going` |

#### Response `200 OK`

```json
{
  "total": 55,
  "going_count": 42,
  "interested_count": 10,
  "not_going_count": 3,
  "attendees": [
    {
      "user_id": "550e8400-e29b-41d4-a716-446655440000",
      "rsvp_id": "rsvp-uuid-here",
      "status": "going",
      "response_message": "Looking forward to it!",
      "rsvp_created_at": "2026-04-25T14:30:00Z"
    }
  ]
}
```

---

### Get event RSVPs (paginated)

<span className="badge badge--get">GET</span> `/api/v1/community-events/{event_id}/rsvps`

Get RSVPs with pagination and optional status filtering.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `status_filter` | `string` | — | `going`, `interested`, or `not_going` |
| `limit` | `integer` | `50` | Max results (1–100) |
| `offset` | `integer` | `0` | Pagination offset |

#### Response `200 OK`

Same shape as the attendees response, with pagination metadata.

---

## My events

### Get my events

<span className="badge badge--get">GET</span> `/api/v1/community-events/my-events`

Get events the authenticated user has RSVP'd to.

#### Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `upcoming_only` | `boolean` | `true` | Only return future events |
| `status_filter` | `string` | — | Filter by RSVP status |
| `limit` | `integer` | `20` | Max results (1–100) |
| `offset` | `integer` | `0` | Pagination offset |

#### Response `200 OK`

```json
{
  "total": 4,
  "offset": 0,
  "limit": 20,
  "has_more": false,
  "events": [
    {
      "id": "abc12345-0000-0000-0000-000000000001",
      "title": "AI Builders Meetup — May 2026",
      "start_time": "2026-05-20T18:00:00Z",
      "status": "scheduled"
    }
  ]
}
```

---

## Event discovery

### Browse upcoming events

<span className="badge badge--get">GET</span> `/api/v1/community-events/browse`

Discover upcoming events with filtering and sorting. Returns only events with `status=scheduled` and `start_time >= now`.

#### Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `event_type` | `string` | — | `virtual`, `in_person`, or `hybrid` |
| `group_id` | `string` (UUID) | — | Filter to a specific group |
| `sort_by` | `string` | `start_time` | Sort field: `start_time` or `attendee_count` |
| `sort_order` | `string` | `asc` | Sort direction: `asc` or `desc` |
| `limit` | `integer` | `20` | Max results (1–100) |
| `offset` | `integer` | `0` | Pagination offset |

#### Response `200 OK`

```json
{
  "total": 18,
  "offset": 0,
  "limit": 20,
  "has_more": false,
  "events": [
    {
      "id": "abc12345-0000-0000-0000-000000000001",
      "title": "AI Builders Meetup — May 2026",
      "start_time": "2026-05-20T18:00:00Z",
      "event_type": "in_person",
      "location": "San Francisco"
    }
  ]
}
```

#### Example

```bash
## Browse in-person upcoming events, soonest first
curl "https://api.ainative.studio/api/v1/community-events/browse?event_type=in_person&sort_by=start_time&sort_order=asc" \
  -H "Authorization: Bearer $API_KEY"
```

```python
resp = requests.get(
    "https://api.ainative.studio/api/v1/community-events/browse",
    headers={"Authorization": f"Bearer {api_key}"},
    params={
        "event_type": "in_person",
        "sort_by": "start_time",
        "sort_order": "asc",
        "limit": 20
    }
)
events = resp.json()["events"]
```

---

## iCal export

### Export event to iCal

<span className="badge badge--get">GET</span> `/api/v1/community-events/{event_id}/export/ical`

Export an event as an iCal (`.ics`) file, compatible with Google Calendar, Apple Calendar, and Outlook.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `event_id` | `string` (UUID) | Yes | Event ID |

#### Response `200 OK`

```json
{
  "ical_content": "BEGIN:VCALENDAR\r\nVERSION:2.0\r\n...",
  "filename": "AI_Builders_Meetup_May_2026_abc12345.ics"
}
```

| Field | Type | Description |
|---|---|---|
| `ical_content` | `string` | iCal-formatted string content |
| `filename` | `string` | Suggested filename derived from the event title and ID |

#### Example

```python
resp = requests.get(
    f"https://api.ainative.studio/api/v1/community-events/{event_id}/export/ical",
    headers={"Authorization": f"Bearer {api_key}"}
)
data = resp.json()
with open(data["filename"], "w") as f:
    f.write(data["ical_content"])
```

---

## Comments

Comments are stored in ZeroDB and can be attached to any content type (videos, articles, tutorials, etc.).

### Post a comment

<span className="badge badge--post">POST</span> `/api/v1/community/comments`

**Auth required.** Post a comment on a content item. Content goes through optional moderation if enabled on your tenant.

#### Request body

```json
{
  "content_type": "video",
  "content_id": 123,
  "comment": "Great tutorial! Very helpful."
}
```

| Field | Type | Required | Description |
|---|---|---|---|
| `content_type` | `string` | Yes | Type of content: `video`, `article`, `tutorial`, etc. |
| `content_id` | `integer` | Yes | Numeric ID of the content item |
| `comment` | `string` | Yes | Comment text (1–5000 characters) |

#### Response `200 OK`

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "user_id": "650e8400-e29b-41d4-a716-446655440001",
  "user_name": "Alice Chen",
  "user_avatar": "https://cdn.ainative.studio/avatars/alice.jpg",
  "content_type": "video",
  "content_id": 123,
  "comment": "Great tutorial! Very helpful.",
  "created_at": "2026-04-25T14:45:00Z",
  "updated_at": null
}
```

#### Errors

| Code | Reason |
|---|---|
| `400` | Comment rejected by content moderation |

### Get comments

<span className="badge badge--get">GET</span> `/api/v1/community/comments/{content_type}/{content_id}`

**Public endpoint — no auth required.** Get comments for a content item, sorted newest first.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `content_type` | `string` | Yes | Content type (e.g., `video`) |
| `content_id` | `integer` | Yes | Content item ID |

#### Query parameters

| Parameter | Type | Default | Description |
|---|---|---|---|
| `limit` | `integer` | `50` | Max comments to return (1–100) |
| `offset` | `integer` | `0` | Pagination offset |

#### Response `200 OK`

```json
{
  "comments": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "user_id": "650e8400-e29b-41d4-a716-446655440001",
      "user_name": "Alice Chen",
      "user_avatar": null,
      "content_type": "video",
      "content_id": 123,
      "comment": "Great tutorial! Very helpful.",
      "created_at": "2026-04-25T14:45:00Z",
      "updated_at": null
    }
  ],
  "total": 7,
  "limit": 50,
  "offset": 0
}
```

### Delete a comment

<span className="badge badge--delete">DELETE</span> `/api/v1/community/comments/{comment_id}`

**Auth required.** Delete a comment. Users can delete their own comments; admins can delete any comment.

#### Path parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| `comment_id` | `string` (UUID) | Yes | Comment UUID |

#### Response `200 OK`

```json
{
  "success": true,
  "message": "Comment 550e8400-e29b-41d4-a716-446655440000 deleted successfully"
}
```

#### Errors

| Code | Reason |
|---|---|
| `403` | You do not own this comment and are not an admin |
| `404` | Comment not found |
