> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fourdos.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Enter a fan in a sponsor's draw on an ad campaign

> Called by the club's backend with its org API key when a signed-in fan enters the draw a campaign's creative leads to. One entry per fan and campaign. When the club's rules pay an entry from the sponsor's XP pool linked to the campaign, the fan earns that XP through the ordinary accrual rail, so the club's earning controls apply and the fan's balance moves as it does for any award.



## OpenAPI

````yaml https://api.develop.fourdos.dev/openapi/partner.json post /v1/ads/campaigns/{campaign_id}/entries
openapi: 3.1.0
info:
  title: 4D OS Partner API
  version: 0.1.0
  description: >-
    REST API for 4D OS partners. Authenticate with your organization API key:
    `Authorization: Bearer <key>`.


    Requests and responses are JSON with `snake_case` field names. Errors share
    one envelope: `{ "error": { "code", "status", "message", "details"? } }`.


    Mutating endpoints that declare it accept an `Idempotency-Key` header so
    retries are safe.


    Bulk-migrating members? See the [Migrating to 4D
    guide](https://docs.fourdos.dev/walkthroughs/migrate-existing-members) for
    the canonical import schema, a worked example, and the `/v1/imports`
    sequence.
servers:
  - url: https://api.develop.fourdos.dev
security:
  - partnerApiKey: []
tags:
  - name: Users
    description: Create, read, and manage users and their org membership
  - name: Imports
    description: Bulk member import jobs (staging → validate → commit)
  - name: API keys
    description: Issue, list, and revoke server-side organization API keys
  - name: Modules
    description: >-
      Publish private modules, install visible modules, and manage their
      credentials
  - name: Ingest
    description: Receive signed native events from an installed module
  - name: Engagement
    description: Browser event tracking (publishable keys) and tracking-key management
  - name: Revenue
    description: Report sales and refunds for the club's revenue dashboards
  - name: Ad delivery
    description: Fill a club site's ad slots, for anonymous or signed-in fans
  - name: Ad entries
    description: Fans entering a sponsor's draw, reported by the club's backend
paths:
  /v1/ads/campaigns/{campaign_id}/entries:
    post:
      tags:
        - Ad entries
      summary: Enter a fan in a sponsor's draw on an ad campaign
      description: >-
        Called by the club's backend with its org API key when a signed-in fan
        enters the draw a campaign's creative leads to. One entry per fan and
        campaign. When the club's rules pay an entry from the sponsor's XP pool
        linked to the campaign, the fan earns that XP through the ordinary
        accrual rail, so the club's earning controls apply and the fan's balance
        moves as it does for any award.
      operationId: createAdCampaignEntry
      parameters:
        - name: campaign_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAdCampaignEntryBody'
      responses:
        '200':
          description: The entry's outcome
          content:
            application/json:
              schema:
                type: object
                properties:
                  entry:
                    $ref: '#/components/schemas/AdCampaignEntry'
                required:
                  - entry
        '401':
          description: Authentication is required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The caller is not an org API key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: >-
            The campaign is not this tenant's, or no active member has that
            member_external_id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: >-
            `AD_CAMPAIGN_INVALID_STATE`: the campaign is not running (not
            active, or outside its flight)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: '`campaign_id` is not a UUID, or the body failed validation'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
        - partnerApiKey: []
components:
  schemas:
    CreateAdCampaignEntryBody:
      type: object
      additionalProperties: false
      properties:
        member_external_id:
          type: string
          minLength: 1
          maxLength: 255
          description: >-
            The fan's id in the club's own system, as the club's backend knows
            it.
      required:
        - member_external_id
    AdCampaignEntry:
      type: object
      additionalProperties: false
      properties:
        status:
          type: string
          enum:
            - recorded
            - duplicate
            - anonymous
          description: >-
            `recorded`: the fan holds the club's personalised content consent
            and had no entry on this campaign; the entry is stored with the fan.
            `duplicate`: the fan already has an entry; nothing is stored and no
            XP is paid, however often or concurrently this is called.
            `anonymous`: the fan does not hold the consent; the entry is counted
            without the fan and pays no XP.
        campaign_id:
          type: string
          format: uuid
        advertiser_name:
          type:
            - string
            - 'null'
          description: The sponsor whose campaign this is, when it has one.
        xp:
          type: string
          enum:
            - funded
            - none
          description: >-
            `funded` when the sponsor's XP pool linked to the campaign pays this
            entry under the club's earning rules. The award is asynchronous and
            the response never carries an amount; an earning control (a daily
            cap, say) can still refuse it, as for any award.
      required:
        - status
        - campaign_id
        - advertiser_name
        - xp
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
            status:
              type: integer
            message:
              type: string
            details:
              type: object
              additionalProperties: true
          required:
            - code
            - status
            - message
      required:
        - error
  securitySchemes:
    partnerApiKey:
      type: http
      scheme: bearer
      description: >-
        Organization API key (`org_...`) sent as `Authorization: Bearer <key>`.
        Keys are scoped to one organization; every request operates within that
        tenant.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.