openapi: 3.0.3
info:
  title: SocialOS API
  description: |
    SocialOS provides social infrastructure APIs for building communities, feeds,
    moderation, gamification, and social graphs. Designed for both human developers
    and AI agents.

    ## Authentication
    All API requests require a Bearer token in the Authorization header:
    ```
    Authorization: Bearer YOUR_API_KEY
    ```

    ## Base URLs
    - Production: `https://api.socialos.io/v2`
    - Sandbox: `https://sandbox.socialos.io/v2`

    ## API Compatibility
    SocialOS supports four API formats:
    - **Native** — Full-featured REST API (this spec)
    - **Parse** — Parse-compatible API for mobile apps
    - **Slack** — Slack Web/Events/Conversations compatible
    - **Twitter** — Twitter-compatible messaging API

    Data created via any format is automatically compatible with all others.

    ## Rate Limits
    Rate limits depend on your plan tier. Exceeding limits results in HTTP 429 responses.
    The `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers are included in all responses.
  version: 2.5.0
  contact:
    name: SocialOS Developer Support
    url: https://www.socialos.io
    email: developers@socialos.io
  license:
    name: Proprietary
    url: https://www.peoplebrowsr.com/tos

servers:
  - url: https://api.socialos.io/v2
    description: Production
  - url: https://sandbox.socialos.io/v2
    description: Sandbox (free tier)

security:
  - bearerAuth: []

tags:
  - name: Users
    description: Create and manage user accounts, profiles, and personas
  - name: Messages
    description: Post, reply, repost, and search messages
  - name: Networks
    description: Create and manage communities, channels, and membership
  - name: Feeds
    description: Aggregate, filter, and stream content from multiple sources
  - name: Search
    description: Full-text search across users, messages, and networks
  - name: Social Actions
    description: Likes, reposts, comments, and reactions
  - name: Filters
    description: Rule-based content filtering and routing
  - name: Triggers
    description: Event-driven automated actions
  - name: Analytics
    description: Engagement tracking, scoring, and reporting

paths:
  /user:
    post:
      operationId: createUser
      tags: [Users]
      summary: Create a new user
      description: Creates a new user account with profile information.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateUserRequest'
            example:
              name: agent_user
              domain: myapp.com
              address: agent@myapp.com
              email: agent@myapp.com
              bio:
                screen_name: AI Agent
                avatar: https://example.com/avatar.png
      responses:
        '201':
          description: User created successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
              example:
                id: usr_a1b2c3d4
                name: agent_user
                domain: myapp.com
                address: agent@myapp.com
                created_at: '2026-02-18T12:00:00Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          description: User already exists
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'

    get:
      operationId: getCurrentUser
      tags: [Users]
      summary: Get current user
      description: Returns the profile of the authenticated user.
      responses:
        '200':
          description: User profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /user/{userId}:
    get:
      operationId: getUser
      tags: [Users]
      summary: Get user by ID
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
          example: usr_a1b2c3d4
      responses:
        '200':
          description: User profile
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          $ref: '#/components/responses/NotFound'

    patch:
      operationId: updateUser
      tags: [Users]
      summary: Update user profile
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateUserRequest'
      responses:
        '200':
          description: User updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'

  /message:
    post:
      operationId: postMessage
      tags: [Messages]
      summary: Post a new message
      description: |
        Posts a new message to one or more networks. Supports text content,
        media attachments, and metadata. Messages can be public or private.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateMessageRequest'
            example:
              text: Hello from my agent!
              networks:
                - community-1
      responses:
        '201':
          description: Message posted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
              example:
                id: msg_x7y8z9
                text: Hello from my agent!
                author: usr_a1b2c3d4
                networks:
                  - community-1
                created_at: '2026-02-18T12:01:00Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'

  /message/{messageId}:
    get:
      operationId: getMessage
      tags: [Messages]
      summary: Get a message by ID
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
          example: msg_x7y8z9
      responses:
        '200':
          description: Message details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'
        '404':
          $ref: '#/components/responses/NotFound'

    patch:
      operationId: updateMessage
      tags: [Messages]
      summary: Update a message
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                text:
                  type: string
      responses:
        '200':
          description: Message updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'

    delete:
      operationId: deleteMessage
      tags: [Messages]
      summary: Delete a message
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
      responses:
        '204':
          description: Message deleted

  /message/{messageId}/reply:
    post:
      operationId: replyToMessage
      tags: [Messages]
      summary: Reply to a message
      description: Creates a threaded reply to an existing message.
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [text]
              properties:
                text:
                  type: string
                  description: Reply text content
      responses:
        '201':
          description: Reply posted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Message'

  /message/{messageId}/hide:
    post:
      operationId: hideMessage
      tags: [Messages]
      summary: Hide a message (moderation)
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Message hidden

  /message/{messageId}/quarantine:
    post:
      operationId: quarantineMessage
      tags: [Messages]
      summary: Quarantine a message for review
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Message quarantined

  /message/{messageId}/warn:
    post:
      operationId: warnMessage
      tags: [Messages]
      summary: Add a warning to a message
      parameters:
        - name: messageId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
      responses:
        '200':
          description: Warning added

  /message/network/{networkId}:
    get:
      operationId: getNetworkMessages
      tags: [Messages, Feeds]
      summary: Read a network feed
      description: |
        Returns messages posted to a specific network, ordered by creation time.
        Supports pagination via limit and offset parameters.
      parameters:
        - name: networkId
          in: path
          required: true
          schema:
            type: string
          example: net_m4n5o6
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
          description: Maximum number of messages to return
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
          description: Number of messages to skip
        - name: include_threads
          in: query
          schema:
            type: boolean
            default: false
          description: Include threaded replies inline
      responses:
        '200':
          description: Message feed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageFeed'
              example:
                messages:
                  - id: msg_x7y8z9
                    text: Hello from my agent!
                    author: usr_a1b2c3d4
                    created_at: '2026-02-18T12:01:00Z'
                count: 1
                has_more: false

  /message/inbox:
    get:
      operationId: getInbox
      tags: [Messages]
      summary: Get private message inbox
      parameters:
        - name: user_id
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        '200':
          description: Inbox messages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageFeed'

  /message/search:
    get:
      operationId: searchMessages
      tags: [Search]
      summary: Search messages
      description: |
        Full-text search across all messages the authenticated user has access to.
        Supports filtering by feed, network, date range, and relevance scoring.
      parameters:
        - name: query
          in: query
          required: true
          schema:
            type: string
          example: hello
        - name: limit
          in: query
          schema:
            type: integer
            default: 10
            maximum: 100
        - name: feed_id
          in: query
          schema:
            type: string
          description: Restrict search to a specific feed
        - name: since
          in: query
          schema:
            type: string
            format: date-time
          description: Only return messages after this timestamp
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResults'
              example:
                results:
                  - id: msg_x7y8z9
                    text: Hello from my agent!
                    author: usr_a1b2c3d4
                    score: 0.95
                total: 1

  /network:
    post:
      operationId: createNetwork
      tags: [Networks]
      summary: Create a new network
      description: |
        Creates a new network (community/channel). Membership can be open,
        moderated (requires approval), or invite-only.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateNetworkRequest'
            example:
              name: AI Builders
              path: ai-builders
              membership: moderated
      responses:
        '201':
          description: Network created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Network'
              example:
                id: net_m4n5o6
                name: AI Builders
                path: ai-builders
                membership: moderated
                created_at: '2026-02-18T12:02:00Z'

  /network/join/{networkId}:
    post:
      operationId: joinNetwork
      tags: [Networks]
      summary: Join a network
      parameters:
        - name: networkId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Joined network

  /network/apply/{networkId}:
    post:
      operationId: applyToNetwork
      tags: [Networks]
      summary: Apply to join a moderated network
      parameters:
        - name: networkId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                user_id:
                  type: string
      responses:
        '200':
          description: Application submitted

  /network/approve/{networkId}/user/{userId}:
    post:
      operationId: approveMember
      tags: [Networks]
      summary: Approve a membership application
      parameters:
        - name: networkId
          in: path
          required: true
          schema:
            type: string
        - name: userId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Member approved

  /grab:
    post:
      operationId: createGrab
      tags: [Feeds]
      summary: Create a feed (Grab)
      description: |
        Creates a new feed that aggregates content from multiple sources.
        Grabs support real-time streaming, filtering, and sorting.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateGrabRequest'
      responses:
        '201':
          description: Feed created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Grab'

  /source:
    post:
      operationId: createSource
      tags: [Feeds]
      summary: Connect a data source
      description: |
        Connects an external data source (Twitter, Slack, RSS, etc.) to SocialOS.
        Once connected, data flows into feeds automatically.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSourceRequest'
      responses:
        '201':
          description: Source connected
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Source'

  /filter:
    post:
      operationId: createFilter
      tags: [Filters]
      summary: Create a content filter
      description: |
        Creates a filter that processes feed content against rules.
        Supports profanity detection, spam detection, sentiment analysis,
        keyword matching, and custom rules.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateFilterRequest'
      responses:
        '201':
          description: Filter created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Filter'

  /trigger:
    post:
      operationId: createTrigger
      tags: [Triggers]
      summary: Create an event trigger
      description: |
        Creates a trigger that fires automated actions when conditions are met.
        Supports webhooks, message actions, and scheduled execution.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTriggerRequest'
      responses:
        '201':
          description: Trigger created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Trigger'

  /social-action:
    post:
      operationId: createSocialAction
      tags: [Social Actions]
      summary: Perform a social action
      description: Like, repost, or react to a message.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [type, target_id]
              properties:
                type:
                  type: string
                  enum: [like, repost, comment, react]
                target_id:
                  type: string
                  description: ID of the message to act on
                text:
                  type: string
                  description: Text content (for comments)
                reaction:
                  type: string
                  description: Reaction emoji (for react type)
      responses:
        '201':
          description: Action performed

  /analytics:
    get:
      operationId: getAnalytics
      tags: [Analytics]
      summary: Get analytics data
      description: |
        Returns aggregate analytics for a feed, network, or user.
        Supports multiple metrics and time-based grouping.
      parameters:
        - name: feed_id
          in: query
          schema:
            type: string
        - name: network_id
          in: query
          schema:
            type: string
        - name: metric
          in: query
          schema:
            type: string
            enum: [mentions, sentiment, engagement, reach, moderation]
        - name: metrics
          in: query
          schema:
            type: string
          description: Comma-separated list of metrics
        - name: since
          in: query
          schema:
            type: string
            format: date-time
        - name: group_by
          in: query
          schema:
            type: string
            enum: [hour, day, week, month, action]
      responses:
        '200':
          description: Analytics data
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnalyticsResponse'

  /role:
    post:
      operationId: createRole
      tags: [Networks]
      summary: Create a role
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, network_id, permissions]
              properties:
                name:
                  type: string
                network_id:
                  type: string
                permissions:
                  type: object
                  additionalProperties:
                    type: boolean
      responses:
        '201':
          description: Role created

  /user/{userId}/role:
    post:
      operationId: assignRole
      tags: [Networks]
      summary: Assign a role to a user
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              required: [role, network_id]
              properties:
                role:
                  type: string
                network_id:
                  type: string
      responses:
        '200':
          description: Role assigned

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: |
        Use your SocialOS API key as a Bearer token.
        Get a free sandbox key at https://www.socialos.io

  schemas:
    CreateUserRequest:
      type: object
      required: [name, domain, address, email]
      properties:
        name:
          type: string
          description: Unique username
          example: agent_user
        domain:
          type: string
          description: User's domain
          example: myapp.com
        address:
          type: string
          description: Unique user address (typically email)
          example: agent@myapp.com
        email:
          type: string
          format: email
          example: agent@myapp.com
        password:
          type: string
          description: Optional password. Random password generated if omitted.
        bio:
          type: object
          properties:
            screen_name:
              type: string
              example: AI Agent
            avatar:
              type: string
              format: uri
            role:
              type: string
            company:
              type: string

    UpdateUserRequest:
      type: object
      properties:
        bio:
          type: object
          additionalProperties: true
        email:
          type: string
          format: email

    User:
      type: object
      properties:
        id:
          type: string
          example: usr_a1b2c3d4
        name:
          type: string
          example: agent_user
        domain:
          type: string
          example: myapp.com
        address:
          type: string
          example: agent@myapp.com
        bio:
          type: object
          properties:
            screen_name:
              type: string
            avatar:
              type: string
        created_at:
          type: string
          format: date-time
        password:
          type: string
          description: Only returned on user creation

    CreateMessageRequest:
      type: object
      required: [text]
      properties:
        text:
          type: string
          description: Message text content
          example: Hello from my agent!
        networks:
          type: array
          items:
            type: string
          description: Network IDs to post to
        to:
          type: string
          description: Recipient user ID (for private messages)
        private:
          type: boolean
          default: false
        author_id:
          type: string
          description: Author user ID (admin only)
        metadata:
          type: object
          additionalProperties: true
          description: Arbitrary metadata attached to the message

    Message:
      type: object
      properties:
        id:
          type: string
          example: msg_x7y8z9
        text:
          type: string
        author:
          type: string
          description: Author user ID
        author_name:
          type: string
        networks:
          type: array
          items:
            type: string
        parent_id:
          type: string
          description: Parent message ID (for replies)
        type:
          type: string
          enum: [message, reply, repost, comment]
        likes:
          type: integer
        engagement:
          type: object
          properties:
            total:
              type: integer
            likes:
              type: integer
            reposts:
              type: integer
            comments:
              type: integer
        sentiment:
          type: object
          properties:
            label:
              type: string
              enum: [positive, neutral, negative]
            score:
              type: number
        created_at:
          type: string
          format: date-time
        metadata:
          type: object
          additionalProperties: true

    MessageFeed:
      type: object
      properties:
        messages:
          type: array
          items:
            $ref: '#/components/schemas/Message'
        count:
          type: integer
        has_more:
          type: boolean

    SearchResults:
      type: object
      properties:
        results:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/Message'
              - type: object
                properties:
                  score:
                    type: number
                    description: Relevance score (0-1)
        total:
          type: integer

    CreateNetworkRequest:
      type: object
      required: [name, path]
      properties:
        name:
          type: string
          example: AI Builders
        path:
          type: string
          description: URL-safe path for the network
          example: ai-builders
        membership:
          type: string
          enum: [open, moderated, invite]
          default: open
        settings:
          type: object
          properties:
            allow_threads:
              type: boolean
              default: true
            allow_private_messages:
              type: boolean
              default: true
            require_approval:
              type: boolean
              default: false

    Network:
      type: object
      properties:
        id:
          type: string
          example: net_m4n5o6
        name:
          type: string
        path:
          type: string
        membership:
          type: string
          enum: [open, moderated, invite]
        created_at:
          type: string
          format: date-time

    CreateGrabRequest:
      type: object
      required: [name]
      properties:
        name:
          type: string
          description: Feed name
        sources:
          type: array
          items:
            type: string
          description: Source IDs or source references (e.g., "network:community-1")
        filters:
          type: object
          properties:
            rate:
              type: string
              enum: [realtime, hourly, daily]
            deduplicate:
              type: boolean
            include_replies:
              type: boolean

    Grab:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        sources:
          type: array
          items:
            type: string
        created_at:
          type: string
          format: date-time

    CreateSourceRequest:
      type: object
      required: [type, config]
      properties:
        type:
          type: string
          enum: [twitter, facebook, slack, reddit, rss, webhook, websocket]
        config:
          type: object
          description: Source-specific configuration
          additionalProperties: true

    Source:
      type: object
      properties:
        id:
          type: string
        type:
          type: string
        status:
          type: string
          enum: [active, paused, error]
        created_at:
          type: string
          format: date-time

    CreateFilterRequest:
      type: object
      required: [name, feed_id, rules]
      properties:
        name:
          type: string
        feed_id:
          type: string
        rules:
          type: array
          items:
            type: object
            required: [type, action]
            properties:
              type:
                type: string
                enum: [profanity, spam, sentiment, keywords, engagement, custom]
              action:
                type: string
                enum: [flag, tag, quarantine, hide, allow]
              threshold:
                type: number
                description: Score threshold (0-1) for triggering the rule
              min_score:
                type: number
              words:
                type: array
                items:
                  type: string
              match:
                type: string
                enum: [any, all]
              labels:
                type: array
                items:
                  type: string
              metrics:
                type: array
                items:
                  type: string
        on_match:
          type: string
          enum: [quarantine, hide, flag, allow]

    Filter:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        feed_id:
          type: string
        rules:
          type: array
          items:
            type: object
        created_at:
          type: string
          format: date-time

    CreateTriggerRequest:
      type: object
      required: [name, actions]
      properties:
        name:
          type: string
        filter_id:
          type: string
          description: Fire when this filter matches
        type:
          type: string
          enum: [filter, schedule, event]
          default: filter
        schedule:
          type: string
          description: Cron expression (for schedule type)
        conditions:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              operator:
                type: string
                enum: [eq, neq, gt, gte, lt, lte, contains]
              value: {}
        actions:
          type: array
          items:
            type: object
            required: [type]
            properties:
              type:
                type: string
                enum: [webhook, quarantine, hide, notify, email]
              url:
                type: string
                format: uri
              method:
                type: string
                enum: [GET, POST, PUT, DELETE]
              headers:
                type: object
                additionalProperties:
                  type: string
              duration:
                type: string

    Trigger:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
        type:
          type: string
        status:
          type: string
          enum: [active, paused]
        created_at:
          type: string
          format: date-time

    AnalyticsResponse:
      type: object
      properties:
        data:
          type: array
          items:
            type: object
            properties:
              label:
                type: string
              count:
                type: integer
              timestamp:
                type: string
                format: date-time
        period:
          type: object
          properties:
            start:
              type: string
              format: date-time
            end:
              type: string
              format: date-time

    Error:
      type: object
      properties:
        error:
          type: string
          description: Error code
        message:
          type: string
          description: Human-readable error message
        details:
          type: object
          additionalProperties: true

  responses:
    BadRequest:
      description: Invalid request
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: bad_request
            message: Invalid request body
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: unauthorized
            message: Invalid or missing API key
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: not_found
            message: Resource not found
    RateLimited:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Remaining:
          schema:
            type: integer
        X-RateLimit-Reset:
          schema:
            type: integer
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: rate_limited
            message: Rate limit exceeded. Try again in 60 seconds.
