---
title: "Opportunities"
description: "Opportunities documentation for Ring Platform"
locale: "en"
---
# Opportunities API

Manage the dual-nature opportunity marketplace with **7 endpoints** supporting both offers and requests across multiple opportunity types.

## Overview

The Ring Platform opportunity system supports a unique dual-nature approach:
- **Offers**: What entities provide (jobs, partnerships, resources)
- **Requests**: What entities need (services, partnerships, resources)

**7 Opportunity Types:**
- Job opportunities
- Partnership opportunities  
- Volunteer opportunities
- Mentorship opportunities
- Resource opportunities
- Event opportunities
- Custom opportunities

## API Endpoints

### `GET /api/opportunities`
List opportunities with role-aware pagination (`limit`, `startAfter`).

### `POST /api/opportunities`
Create an opportunity. JSON body validated by `createOpportunityBodySchema`, then `features/opportunities/services/create-opportunity`. Returns `{ opportunity }` with **201**.

Required fields: `title`, `briefDescription`, `organizationId`, `category`, `location`, `visibility`, `contactInfo.linkedEntity`, `contactInfo.contactAccount`.

### `GET /api/opportunities/{id}`
Get opportunity details by ID.

### `GET /api/opportunities/search`
Search opportunities (query parameters per route implementation).

### `PUT /api/opportunities/{id}` / `PATCH /api/opportunities/{id}`
Update opportunity by ID (canonical HTTP path). Prefer Server Actions for UI flows in alpha.

### `DELETE /api/opportunities/{id}`
Delete opportunity.

### `POST /api/opportunities/upload`
Upload opportunity attachments.

**REST create** is `POST /api/opportunities` (shared schema with MCP). The add-opportunity UI may still use the **`createOpportunity` Server Action** (`app/_actions/opportunities.ts`) for FormData; both call the same service.

## Data model

API and server services use types from `features/opportunities/types`. **Responses and server actions expose `SerializedOpportunity`** — date fields are ISO strings (safe for JSON and React client components). The legacy `Opportunity` interface still documents Firestore `Timestamp` shapes for `DB_BACKEND_MODE=firebase-full` only.

{`type OpportunityType =
  | 'offer' | 'request' | 'partnership' | 'volunteer' | 'mentorship'
  | 'resource' | 'event' | 'ring_customization' | /* … */

interface SerializedOpportunity {
  id: string
  type: OpportunityType
  title: string
  briefDescription: string
  fullDescription?: string
  status: 'draft' | 'pending' | 'active' | 'closed' | 'expired' | 'archived'
  createdBy: string
  organizationId: string
  dateCreated: string   // ISO 8601
  dateUpdated: string
  expirationDate: string
  applicationDeadline?: string
  category: string
  tags: string[]
  location: string
  budget?: { min?: number; max: number; currency?: string }
  requiredSkills: string[]
  visibility: 'public' | 'subscriber' | 'member' | 'confidential'
  isConfidential: boolean
  contactInfo: { linkedEntity: string; contactAccount: string }
  applicantCount: number
  // …see features/opportunities/types/index.ts
}`}

### PostgreSQL mapping

`DatabaseService` query rows `{ id, data }` are mapped with `mapDbQueryRowToSerializedOpportunity()` in `features/opportunities/lib/opportunity-db-mapper.ts`. Do **not** use `lib/converters/opportunity-converter.ts` on the Postgres path — that module is a **Firestore-only legacy** `FirestoreDataConverter`.

### Post-mutation discovery sync

Creates, updates, deletes, and status changes call `syncOpportunityDiscovery()` which:

1. **`revalidateTag`** — invalidates `unstable_cache` opportunity lists (`lib/cached-data.ts`)
2. **`revalidatePath`** — refreshes `/[locale]/opportunities`, `/[locale]/opportunities/[id]`, and `/[locale]/opportunities/my`
3. **Tunnel** — publishes `opportunity:created|updated|deleted` on the `opportunities` channel

There is no separate search-index reindex command; discovery queries run against PostgreSQL JSONB. Tunnel publish is shared via `lib/discovery/sync-discovery.ts` (see [Discovery mutation sync](../architecture/discovery-mutation-sync)).

## Opportunity Types

### Job Opportunities
- Full-time positions
- Part-time roles
- Contract work
- Internships

### Partnership Opportunities
- Business partnerships
- Strategic alliances
- Joint ventures
- Collaboration projects

### Volunteer Opportunities
- Non-profit work
- Community service
- Pro bono projects
- Social impact initiatives

### Mentorship Opportunities
- Professional mentoring
- Industry guidance
- Skill development
- Career coaching

### Resource Opportunities
- Equipment sharing
- Space rental
- Service exchange
- Knowledge sharing

### Event Opportunities
- Conference speaking
- Workshop hosting
- Networking events
- Training sessions

## Implementation Examples

### Create opportunity (Server Action)

Use the add-opportunity form pattern with `useActionState` and `createOpportunity` from `app/_actions/opportunities.ts` — see [API integration examples](/en/docs/examples/api-integration).

### List opportunities

{`const response = await fetch('/api/opportunities?limit=10', { credentials: 'include' })
const { opportunities, lastVisible } = await response.json()`}

### Search opportunities

{`const response = await fetch('/api/opportunities/search?q=react&limit=20', {
  credentials: 'include',
})
const data = await response.json()`}

## Access Control

### Opportunity Visibility
- **Public Opportunities**: Visible to all users
- **Confidential Opportunities**: Require CONFIDENTIAL role

### Opportunity Management
- **Create**: Server Action from add-opportunity UI (`createOpportunity`)
- **Update/Delete**: Server Actions or `PUT|PATCH /api/opportunities/{id}`, `DELETE /api/opportunities/{id}`
- **Apply**: In-app flows (no dedicated `/apply` REST route in alpha)

## Advanced Features

### Deadline Management
- Automatic opportunity expiration
- Deadline notifications
- Application cutoff handling

### Smart Matching
- AI-powered opportunity recommendations
- Skill-based matching
- Location and preference filtering

### Analytics
- Application tracking
- Performance metrics
- Success rate analysis

---

*Ready to post your first opportunity? Start with our [Getting Started](/en/docs/getting-started) guide.*
