Campus One

App Events API

Let connected applications push calendar events to Campus One users who have granted consent.

App Events API

Connected applications can push calendar and scheduling events directly into a consented user's Campus One dashboard. Events appear in the Upcoming card (showing the next event) and in the This Week section (showing all events in the current calendar week).


Architectural Flow

Loading diagram...

Authentication & Authorization

All event requests require standard OIDC User Access Tokens.

  • Required Scope: events
  • Method: Bearer Token Authentication
  • Header format: Authorization: Bearer <access_token>
  • Admin prerequisite: The permEvents flag must be enabled for your app in the Campus One admin console under SSO Config → Permissions.

The recipient user and origin app are resolved from the access token — apps do not supply a userId in the request body, preventing spoofing.

[!WARNING] If the token is expired, lacks the events scope, or the app's permEvents flag is disabled, the gateway returns 401 Unauthorized or 403 Forbidden.


REST API Reference

Create Event

Push a calendar event to the authenticated user.

POST /api/apps/events

Headers

HeaderTypeDescription
AuthorizationstringRequired. Bearer <access_token> with the events scope.
Content-TypestringRequired. Must be application/json.
Idempotency-KeystringOptional. Supply a unique key to prevent duplicate events if the request is retried. Keys are scoped per app and expire after 24 hours.

Request Payload

FieldTypeRequiredDescription
titlestringYesEvent title (maximum 200 characters).
descriptionstringNoAdditional details about the event (maximum 1 000 characters).
startsAtstringYesISO 8601 datetime when the event begins (e.g. 2026-06-15T14:00:00Z).
endsAtstringNoISO 8601 datetime when the event ends.
locationstringNoVenue or meeting link (maximum 300 characters).
urlstringNoDeep-link back into your app for full event details.

Example Integration

curl -X POST https://auth.campusone.com.ng/api/apps/events \
  -H "Authorization: Bearer c1_act_abc123xyz" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: club-niletech-hackathon-2026" \
  -d '{
    "title": "NileTech Hackathon Finals",
    "description": "Final round of the 2026 NileTech Hackathon. Teams present to judges.",
    "startsAt": "2026-06-15T09:00:00+01:00",
    "endsAt": "2026-06-15T17:00:00+01:00",
    "location": "Engineering Lecture Theatre, Block C",
    "url": "https://nilehub.nileuniversity.edu.ng/events/hackathon-2026"
  }'
const createEvent = async () => {
  const response = await fetch('https://auth.campusone.com.ng/api/apps/events', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer c1_act_abc123xyz',
      'Content-Type': 'application/json',
      'Idempotency-Key': 'club-niletech-hackathon-2026'
    },
    body: JSON.stringify({
      title: 'NileTech Hackathon Finals',
      description: 'Final round of the 2026 NileTech Hackathon.',
      startsAt: '2026-06-15T09:00:00+01:00',
      endsAt: '2026-06-15T17:00:00+01:00',
      location: 'Engineering Lecture Theatre, Block C',
      url: 'https://nilehub.nileuniversity.edu.ng/events/hackathon-2026'
    })
  });

  if (!response.ok) {
    const err = await response.json();
    throw new Error(`Failed to create event: ${err.message}`);
  }

  const result = await response.json();
  console.log('Event created:', result.id);
};
import requests

headers = {
    "Authorization": "Bearer c1_act_abc123xyz",
    "Content-Type": "application/json",
    "Idempotency-Key": "club-niletech-hackathon-2026"
}

payload = {
    "title": "NileTech Hackathon Finals",
    "description": "Final round of the 2026 NileTech Hackathon.",
    "startsAt": "2026-06-15T09:00:00+01:00",
    "endsAt": "2026-06-15T17:00:00+01:00",
    "location": "Engineering Lecture Theatre, Block C",
    "url": "https://nilehub.nileuniversity.edu.ng/events/hackathon-2026"
}

res = requests.post(
    "https://auth.campusone.com.ng/api/apps/events",
    json=payload,
    headers=headers
)

if res.status_code == 201:
    print("Event created! ID:", res.json()["id"])
else:
    print("Failed:", res.status_code, res.text)

Response Schemas

[!NOTE] The live, always-accurate schemas are published at the interactive API reference. The example below is illustrative — IDs are opaque strings (cuids) with no fixed prefix.

200 OK

The response body is the full created AppEvent record.

{
  "id": "clh83kf1a0001st09k4m2p9zx",
  "userId": "clx8z2abc1230009ab12cd34",
  "appId": "clw7a1def4560002gh56ij78",
  "title": "NileTech Hackathon Finals",
  "description": "Final round of the 2026 NileTech Hackathon.",
  "startsAt": "2026-06-15T08:00:00.000Z",
  "endsAt": "2026-06-15T16:00:00.000Z",
  "location": "Engineering Lecture Theatre, Block C",
  "url": "https://nilehub.nileuniversity.edu.ng/events/hackathon-2026",
  "createdAt": "2026-05-28T10:00:00.000Z",
  "updatedAt": "2026-05-28T10:00:00.000Z"
}

Error responses

A 401 (authentication) is rejected at the gateway and returns { "error": "..." }. A 400 (validation) or 403 (authorization) comes from the endpoint and returns the richer { code, status, message } object. See Status Codes & Errors for the canonical reference.

StatusBodyCause
400{ code, status, message, data }Required fields missing or invalid (e.g. startsAt is not a valid ISO 8601 datetime).
401{ error }Bearer token missing, invalid, expired, or not bound to a user.
403{ code, status, message }Token lacks the events scope, or the app's permEvents flag is disabled.

How Events Surface in the Dashboard

SectionBehaviour
Upcoming cardShows the single next event with startsAt ≥ now, sorted ascending.
This Week sectionShows all events whose startsAt falls within the current Monday–Sunday window. If no events exist this week, the section is retitled Upcoming and shows the next 5 future events instead.

Events from all apps the student has consented to are merged and sorted together by startsAt.


Scope & Permission Requirements

RequirementWhere it is set
events scope in the OIDC tokenThe student grants this during the OAuth consent flow.
permEvents = true on the app's SSO ConfigAn admin enables this in the Campus One admin console under Apps → [Your App] → SSO Config → Permissions.

Both must be satisfied for POST /api/apps/events to succeed.

On this page