basePath: /api/v1
consumes:
- application/json
definitions:
  apierror.ErrorAPI:
    properties:
      code:
        type: string
      message:
        type: string
      reason:
        type: string
    type: object
  v1.ArchiveCampaignResponse:
    properties:
      success:
        description: Success indicates whether the campaign deletion operation was
          successful or not.
        example: true
        type: boolean
    type: object
  v1.CampaignListResponse:
    properties:
      campaigns:
        description: List of all campaigns satisfying filters
        items:
          $ref: '#/definitions/v1.CampaignResponse'
        type: array
      next:
        description: |-
          Pagination token that is used to retrieve the next page.

          See [Pagination](#section/Pagination) for more details.
        example: aWQ6MDE5NmVkMzEtYTEzMy03M2Y3LThmZjEtMDA5NmM5OWU4NmI3
        type: string
    type: object
  v1.CampaignResponse:
    properties:
      channel:
        description: Messaging channel for the campaign
        enum:
        - sms
        - rcs
        example: sms
        type: string
      contact_filters:
        allOf:
        - $ref: '#/definitions/v1.ContactFilters'
        description: Contacts filters decide what contacts will be included in the
          campaign
      created_at:
        description: Campaign creation date in UTC
        example: "2025-01-01T00:00:00Z"
        type: string
      id:
        description: Unique campaign ID
        example: 01961600-b921-7cc9-9849-000000000001
        type: string
      message_template:
        allOf:
        - $ref: '#/definitions/v1.MessageTemplate'
        description: Message payload
      name:
        description: User-defined campaign name
        example: My first campaign
        type: string
      pricing:
        allOf:
        - $ref: '#/definitions/v1.PricingResponse'
        description: Campaign price
      scheduled_for:
        description: Scheduled time to start campaign
        example: "2025-01-01T00:00:00Z"
        type: string
      sender:
        description: SenderID (alpha name) registered in Apifonica, that will be used
          as a sender
        example: AlphaName
        type: string
      started_at:
        description: Actual time that campaign started
        example: "2025-01-01T00:00:00Z"
        type: string
      status:
        description: |-
          * `draft` - campaign draft has been created
          * `new` - campaign has been created and not launched
          * `scheduled` - campaign has been scheduled and not launched
          * `running` - campaign has been launched
          * `paused` - campaign has been paused
          * `canceled` - campaign has been canceled
          * `finished` - campaign has finished processing all messages
          * `archived` - campaign has been archived
        enum:
        - draft
        - new
        - scheduled
        - running
        - paused
        - canceled
        - finished
        - archived
        example: new
        type: string
      tag:
        description: Custom string tag associated with the campaign
        type: string
      total_contacts:
        description: Total number of contacts for the campaign
        example: 10000
        type: integer
      updated_at:
        description: Campaign last update date in UTC
        example: "2025-01-01T00:00:00Z"
        type: string
      url_shortener:
        allOf:
        - $ref: '#/definitions/v1.ShortenerResponse'
        description: URL shortener configuration
    type: object
  v1.CampaignStats:
    properties:
      delivered:
        example: 500
        type: integer
      done:
        description: Messages in final status
        example: 600
        type: integer
      expired:
        example: 0
        type: integer
      failed:
        example: 0
        type: integer
      processing:
        description: Messages in intermediary status that are currently being processed
        example: 400
        type: integer
      queued:
        example: 300
        type: integer
      rejected:
        example: 50
        type: integer
      revoked:
        example: 0
        type: integer
      seen:
        example: 0
        type: integer
      sent:
        example: 100
        type: integer
      total:
        description: Total messages in the campaign
        example: 1000
        type: integer
      undeliverable:
        example: 50
        type: integer
    type: object
  v1.CampaignStatsResponse:
    properties:
      id:
        description: Unique campaign ID
        example: 01961600-b921-7cc9-9849-000000000001
        type: string
      stats:
        allOf:
        - $ref: '#/definitions/v1.CampaignStats'
        description: Campaign statistics
      status:
        description: |-
          * `draft` - campaign draft has been created
          * `new` - campaign has been created and not launched
          * `scheduled` - campaign has been scheduled and not launched
          * `running` - campaign has been launched
          * `paused` - campaign has been paused
          * `canceled` - campaign has been canceled
          * `finished` - campaign has finished processing all messages
          * `archived` - campaign has been archived
        enum:
        - draft
        - new
        - scheduled
        - running
        - paused
        - canceled
        - finished
        - archived
        example: new
        type: string
    type: object
  v1.CarrierResponse:
    properties:
      country_code:
        description: Country code
        example: PL
        type: string
      name:
        description: Name of the carrier
        example: Play
        type: string
      network_code:
        description: Network code
        example: "26006"
        type: string
    type: object
  v1.Contact:
    properties:
      phone_number:
        description: |-
          Contact phone number.

          Phone number will be normalized automatically. See more in [Create Contacts](#tag/createContacts) description above.
        example: "358942000000"
        type: string
      variables:
        additionalProperties:
          type: string
        description: |-
          Variables are key-value pairs that can be used to dynamically change the content of the message

          Format is JSON. Only string values are allowed.

          All keys must follow the regex `^[a-zA-Z0-9_-]+$` and be no longer than 100 characters. Values can be any string no longer than 100 characters.

          Check [Contacts](#tag/Contacts) for more details.
        example:
          customer_id: "101"
          name: Alex
        type: object
    required:
    - phone_number
    type: object
  v1.ContactFilters:
    properties:
      label_ids:
        description: Include all contacts with these label IDs in the campaign
        example:
        - 01961600-b921-7cc9-9849-000000000001
        - 01961600-b921-7cc9-9849-000000000002
        items:
          type: string
        minItems: 1
        type: array
    required:
    - label_ids
    type: object
  v1.ContactWithCountryCode:
    properties:
      country_code:
        description: Country code where carrier operates
        example: PL
        type: string
      phone_number:
        description: |-
          Contact phone number.

          Phone number will be normalized automatically. See more in [Create Contacts](#tag/createContacts) description above.
        example: "358942000000"
        type: string
      variables:
        additionalProperties:
          type: string
        description: |-
          Variables are key-value pairs that can be used to dynamically change the content of the message

          Format is JSON. Only string values are allowed.

          All keys must follow the regex `^[a-zA-Z0-9_-]+$` and be no longer than 100 characters. Values can be any string no longer than 100 characters.

          Check [Contacts](#tag/Contacts) for more details.
        example:
          customer_id: "101"
          name: Alex
        type: object
    required:
    - phone_number
    type: object
  v1.CreateCampaignRequest:
    properties:
      channel:
        description: |-
          Messaging channel for the campaign.

          Depending on the channel, you should provide appropriate `sender` and `message_template`.
        enum:
        - sms
        - rcs
        example: sms
        type: string
      contact_filters:
        allOf:
        - $ref: '#/definitions/v1.ContactFilters'
        description: |-
          Contact filters decide what contacts will be included in the campaign.

          You may add contacts even after campaign creation, but not after launch.
      draft:
        description: |-
          Draft indicates whether to create campaign in `draft` status.

          This is helpful when the campaign payload/contacts are not finalized yet.
          You can also preview the campaign pricing details in the response
          and decide whether to run the campaign or not.

          Default value: `false`.

          Draft campaigns cannot be scheduled or started until confirmed - see [Confirm campaign](#operation/confirmCampaign).

          Draft campaigns can be discarded - see [Delete campaign](#operation/deleteCampaign).
        example: false
        type: boolean
      message_template:
        allOf:
        - $ref: '#/definitions/v1.MessageTemplate'
        description: |-
          Message payload to be sent.

          You can use variable templating here. For example, `{{ name }}` will be replaced with the value of `name` variable in the contact.

          Each variable must start with `{{` and end with `}}`. Variables themselves can only contain letters, numbers, underscores, and dashes (regex `[a-zA-Z0-9_-]`).
          Templates are validated - you will receive an error if the template is invalid.

          Currently, this functionality only works for `sms` channel.

          Check out [Contacts - Variables section](#tag/Contacts) for additional details.
      name:
        description: User-defined campaign name
        example: My first campaign
        type: string
      sender:
        description: |-
          SenderID (alpha name) registered in Apifonica.

          Go to your [Personal Account](https://account-smsbot.apifonica.com/dashboard/alpha-names/register) to register a new sender.
        example: MyAlpha
        type: string
      tag:
        description: Custom string tag associated with the campaign. Max length 50
          characters.
        example: marketing-2025
        maxLength: 50
        type: string
      url_shortener:
        allOf:
        - $ref: '#/definitions/v1.Shortener'
        description: Configuration for URL shortener (short links functionality)
    required:
    - channel
    - contact_filters
    - message_template
    - name
    - sender
    type: object
  v1.CreateContactsRequest:
    properties:
      contacts:
        description: List of contacts
        items:
          $ref: '#/definitions/v1.Contact'
        type: array
      exclude_landlines:
        description: |-
          Flag specifying whether to filter out landline (non-mobile) numbers

          Default: `true`
        example: true
        type: boolean
      labels:
        description: List of labels to associate with the contacts
        items:
          $ref: '#/definitions/v1.Label'
        minItems: 1
        type: array
      normalization_country_code:
        description: |-
          Two-letter ISO 3166-1 alpha-2 country code, specifying that contact numbers should be normalized
          with regard to this country.

          See more in [Create Contacts](#tag/createContacts) description above.
        example: FI
        type: string
    required:
    - labels
    type: object
  v1.CreateContactsResponse:
    properties:
      contacts:
        description: List of valid created contacts
        items:
          $ref: '#/definitions/v1.ContactWithCountryCode'
        type: array
      filtered:
        allOf:
        - $ref: '#/definitions/v1.FilteredContacts'
        description: List of filtered contacts
      label_ids:
        description: |-
          Created label IDs.

          These can be used as a `label_ids` field in [Create campaign](#operation/createCampaign).
        example:
        - 01961600-b921-7cc9-9849-000000000001
        - 01961600-b921-7cc9-9849-000000000002
        items:
          type: string
        type: array
      total_duplicates:
        description: Number of duplicate contacts with the same phone number (filtered)
        example: 0
        type: integer
      total_existing_contacts:
        description: Total number of contacts that have already been created before
        example: 10
        type: integer
      total_invalid:
        description: Number of contacts with invalid phone number (filtered)
        example: 10
        type: integer
      total_landlines:
        description: Number of contacts with landline (non-mobile) numbers (filtered)
        example: 20
        type: integer
      total_new_contacts:
        description: Total number of contacts created, without duplicate, invalid
          contacts, etc.
        example: 1000
        type: integer
    type: object
  v1.ErrorResponse:
    properties:
      description:
        example: Campaign not found
        type: string
      error:
        example: resource_not_found
        type: string
      status:
        example: error
        type: string
    type: object
  v1.FilteredContacts:
    properties:
      duplicates:
        description: List of duplicate contacts
        items:
          $ref: '#/definitions/v1.Contact'
        type: array
      invalid:
        description: List of invalid contacts
        items:
          $ref: '#/definitions/v1.Contact'
        type: array
      landlines:
        description: List of landline contacts (only if `filter_landlines` flag was
          set to `true`)
        items:
          $ref: '#/definitions/v1.Contact'
        type: array
    type: object
  v1.Label:
    properties:
      name:
        description: User-defined label name
        example: Retail customers
        type: string
    required:
    - name
    type: object
  v1.MessageTemplate:
    properties:
      payload:
        description: |-
          Payload contains full message payload.

          For `sms` messages, payload has the form `{"text": "<text message>"}`.

          Refer to [Apifonica Send message](https://docs.apifonica.com/platform/#operation/sendMessage) `text` parameter for detailed specification.

          For `rcs` messages, payload has the form e.g. `{"text_payload": {"text": "<text message>"}}`.

          Refer to [Apifonica Send message](https://docs.apifonica.com/platform/#operation/sendMessage) `rcs_payload` parameter for full specification.
        type: object
      type:
        description: |-
          Type decides message content (text, media, etc.).

          Refer to [Apifonica Send message](https://docs.apifonica.com/platform/#operation/sendMessage) `type` parameter for detailed specification.
        enum:
        - text
        - file
        - card
        - carousel
        example: text
        type: string
    required:
    - payload
    type: object
  v1.PriceResponse:
    properties:
      carrier:
        allOf:
        - $ref: '#/definitions/v1.CarrierResponse'
        description: Carrier information
      contacts:
        description: Number of contacts
        example: 10000
        type: integer
      cost:
        description: Cost of a single message
        example: 0.056
        type: number
    type: object
  v1.PricingResponse:
    properties:
      currency:
        description: Currency
        example: eur
        type: string
      prices:
        description: |-
          Pricing breakdown by carrier/network:
          - how many contacts are sent via each carrier
          - how much a particular destination costs
        items:
          $ref: '#/definitions/v1.PriceResponse'
        type: array
      total_cost:
        description: Total cost of the campaign
        example: 560
        type: number
    type: object
  v1.ReportListResponse:
    properties:
      next:
        description: |-
          Pagination token that is used to retrieve the next page.

          See [Pagination](#section/Pagination) for more details.
        example: aWQ6MDE5NmVkMzEtYTEzMy03M2Y3LThmZjEtMDA5NmM5OWU4NmI3
        type: string
      reports:
        description: List of all reports satisfying filters
        items:
          $ref: '#/definitions/v1.ReportResponse'
        type: array
    type: object
  v1.ReportResponse:
    properties:
      campaign_id:
        description: Campaign ID the report belongs to
        example: 01961600-b921-7cc9-9849-000000000001
        type: string
      created_at:
        description: |-
          Report creation date in UTC.

          Note - this is not the report generation date (see `generated_at`), but when this API object was first created.
        example: "2025-01-01T00:00:00Z"
        type: string
      download_url:
        description: Report download URL
        example: https://storage.apifonica.com/download/01961600-b921-7cc9-9849-000000000001.csv
        type: string
      expires_at:
        description: |-
          Report download URL expiration date in UTC.

          This is when the URL will no longer be accessible.
          When you request a report via the API, the URL will get refreshed preemptively if it is expiring in less than 3 days.
        example: "2025-01-03T00:00:00Z"
        type: string
      format:
        description: |-
          Report file format. Possible values:
          * `csv`
        example: csv
        type: string
      generated_at:
        description: |-
          Report last generation date in UTC.

          This is when the report file was last refreshed.
          In other words, this is the last time when the report data had changes.
        example: "2025-01-02T00:00:00Z"
        type: string
      id:
        description: Unique report ID
        example: 01961600-b921-7cc9-9849-000000000001
        type: string
      status:
        description: |-
          * `pending` - report is yet to be generated (campaign is in progress)
          * `generating` - report is currently being generated
          * `incomplete` - report has been generated, but there might still be updates (some messages can change status)
          * `complete` - report has been generated and is in final state (all messages are in final statuses)
        example: complete
        type: string
      type:
        description: |-
          Report type/kind. Possible values:
          * `campaign_detailed_stats` - report with full per-message campaign details
            * `sms` reports columns: `Created`, `From`, `To`, `Status`, `Text`, `Direction`, `Message SID`
            * `rcs` reports columns: `Created`, `From`, `To`, `Status`, `Reason`, `Payload`, `Direction`, `Message SID`
        example: campaign_detailed_stats
        type: string
      updated_at:
        description: Report last update date in UTC. This includes any update - status
          change, contents change, URL refresh, etc.
        example: "2025-01-01T00:00:00Z"
        type: string
    type: object
  v1.ScheduleRequest:
    properties:
      scheduled_for:
        description: Time to start campaign
        example: "2025-01-01T00:00:00Z"
        type: string
    required:
    - scheduled_for
    type: object
  v1.Shortener:
    properties:
      enabled:
        description: |-
          Enable short links functionality (shortened URLs and clicks tracking).

          If set to `true`, every link in the `message_template` will be replaced with a unique short link
          that looks like `https://apif.me/ABCDE`. When the user follows the link, they will get seamlessly
          redirected to the original URL.

          Only valid links starting with `http://` or `https://` will be replaced like this.
          If you need to replace links without the http scheme, use `hints` parameter below.
        example: true
        type: boolean
      hints:
        description: |-
          Allows to specify what parts of message payload to treat as URLs.

          For example, if your text payload is `"Click to visit our site >my-site.com<"`
          and you specify `my-site.com` as a hint, it will get URL-shortened, resulting in
          this text: `"Click to visit our site >https://apif.me/ABCDE<"`.
        example:
        - my-site.com
        items:
          type: string
        type: array
      remove_scheme:
        description: |-
          When enabled, short links in the message payload will have their scheme stripped
          (e.g. `apif.me/ABCDE` instead of `https://apif.me/ABCDE`).
        example: false
        type: boolean
    required:
    - enabled
    type: object
  v1.ShortenerResponse:
    properties:
      enabled:
        description: Whether short links functionality is enabled in the campaign
        example: true
        type: boolean
      hints:
        description: Hints
        example:
        - my-site.com
        items:
          type: string
        type: array
      remove_scheme:
        description: Whether the scheme is stripped from short links in the message
          payload
        example: false
        type: boolean
    type: object
  v1.smsPayloadExample:
    properties:
      text:
        example: Hello world!
        type: string
    type: object
host: campaign-manager.apifonica.com
info:
  contact:
    email: info@apifonica.com
    name: Apifonica Support
    url: https://www.apifonica.com/en/company/contacts
  description: "## Overview\nApifonica Campaign Manager API allows you to plan, launch
    and track messaging campaigns that can reach\nyour clients via one of Apifonica-supported
    channels.\n\n## Authentication\nAuthorization scheme: **Basic Auth**.\n\nYou need
    to authenticate all your requests using valid Apifonica credentials pair - `account_sid`
    and `account_token`.\n\nYou can find them in your [Apifonica Personal Account](https://account-smsbot.apifonica.com/dashboard/integrations).\n\nMore
    details can be found in [Apifonica FAQ](https://www.apifonica.com/en/developers/faq/basics/).\n\n##
    Pagination\n\nSome API endpoints support pagination to efficiently retrieve large
    collections in manageable chunks.\nYou may traverse collections page by page providing
    the parameters listed below.\n\nAll items are sorted based on creation date in
    **descending order**.\n\n### Request query parameters\n\n- **`next`** (string,
    optional):  \n  Pagination token from previous response. In order to retrieve
    the next page of results, provide this value\n  in query parameters.  \n  To retrieve
    the **first page**, just omit this parameter.\n\n- **`limit`** (int, optional):
    \ \n  Limits the number of returned items. Each resource has a specific maximum
    allowed `limit` value, you will find these\n  in the documentation for each endpoint.
    \ \n  If the parameter is omitted, the maximum allowed value will be used by default.
    \ \n  If provided limit is greater than maximum, the maximum allowed value will
    be used. \n\n### Response format\n\nEach paginated response looks like the following:\n\n-
    A specific resource array, e.g. `campaigns`, `reports`, etc.    \n  This is the
    list of all resources satisfying request filters and constrained by `limit` parameter.
    \ \n  If there are more items available, the `next` parameter will be non-empty.\n\n-
    **`next`** (string, optional):  \n  Pagination token that can be used to fetch
    the next page of results.  \n  When this field is omitted, it means the current
    page is the last page.\n\n## URL shortening\nWhenever you need to include a long
    URL in your message template, you may use Apifonica URL shortener capabilities\nto
    shorten it. This will result in a short URL that looks like `https://apif.me/ABCDE`.
    \n\nTo enable this functionality, specify `url_shortener` configuration in [Create
    Campaign](#operation/createCampaign) request.\n\n### Clicks tracking\n_Coming
    soon!_\n"
  termsOfService: https://www.apifonica.com/public/legal/apifonica_terms_of_service.pdf
  title: Campaign Manager
  version: "1.0"
  x-logo:
    altText: Apifonica logo
    url: https://apifonica.com/public/img/logo.svg
paths:
  /campaigns:
    get:
      description: List all campaigns.
      operationId: listCampaigns
      parameters:
      - description: |-
          Filter by messaging channel.

          Can be a single value or a comma-separated list.

          Valid channels: `sms`, `rcs`.
        example: sms,rcs
        in: query
        name: channel
        type: string
      - description: |-
          Number of retrieved items per page.

          Default value is **20**.

          Maximum value is **100**.

          If provided limit is greater than maximum, a validation error will be returned.
        example: "10"
        in: query
        name: limit
        type: string
      - description: Filter by campaign name (partial, case-insensitive match).
        example: Black Friday
        in: query
        name: name_like
        type: string
      - description: |-
          Pagination token that is used to retrieve the next page.

          See [Pagination](#section/Pagination) for more details.
        example: aWQ6MDE5NmVkMzEtYTEzMy03M2Y3LThmZjEtMDA5NmM5OWU4NmI3
        in: query
        name: next
        type: string
      - description: Filter by sender number/alphanumeric ID (exact match).
        example: MyAlpha
        in: query
        name: sender
        type: string
      - description: |-
          Filter by campaign status.

          Can be a single value or a comma-separated list.

          Valid statuses: `draft`, `new`, `scheduled`, `running`, `paused`, `canceled`, `finished`, `archived`.

          Note: `archived` campaigns are hidden by default unless explicitly requested.
        example: running,paused
        in: query
        name: status
        type: string
      - description: Filter by campaign tag (exact match).
        example: marketing-2025
        in: query
        name: tag
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignListResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: List campaigns
      tags:
      - Campaigns
    post:
      description: |
        Create campaign in `draft` or `new` status (more about these statuses in the description of `draft` flag below).

        A campaign must be associated with one or more _Labels_. Check [Contacts section](#tag/Contacts) for more details on labels and contacts.
      operationId: createCampaign
      parameters:
      - description: Campaign details
        in: body
        name: request
        required: true
        schema:
          allOf:
          - $ref: '#/definitions/v1.CreateCampaignRequest'
          - properties:
              message_template:
                allOf:
                - $ref: '#/definitions/v1.MessageTemplate'
                - properties:
                    payload:
                      $ref: '#/definitions/v1.smsPayloadExample'
                  type: object
            type: object
      responses:
        "201":
          description: Created
          schema:
            allOf:
            - $ref: '#/definitions/v1.CampaignResponse'
            - properties:
                message_template:
                  allOf:
                  - $ref: '#/definitions/v1.MessageTemplate'
                  - properties:
                      payload:
                        $ref: '#/definitions/v1.smsPayloadExample'
                    type: object
              type: object
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Create campaign
      tags:
      - Campaigns
  /campaigns/{id}:
    delete:
      description: Delete the campaign. Only campaigns in `draft`, `new` or `scheduled`
        status can be deleted.
      operationId: deleteCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "204":
          description: No Content
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Delete campaign
      tags:
      - Campaigns
    get:
      operationId: getCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Get campaign
      tags:
      - Campaigns
  /campaigns/{id}/archive:
    patch:
      description: Archive the campaign in status 'finished' or 'canceled'.
      operationId: archiveCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.ArchiveCampaignResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Archive campaign
      tags:
      - Campaigns
  /campaigns/{id}/cancel:
    patch:
      description: Cancel a stopped campaign. Canceled campaign cannot be resumed/restarted.
      operationId: cancelCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Cancel campaign
      tags:
      - Campaigns
  /campaigns/{id}/confirm:
    patch:
      description: |-
        Confirm the campaign draft.
        This changes campaign status to `new` and allows to schedule or start the campaign.
      operationId: confirmCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Confirm campaign
      tags:
      - Campaigns
  /campaigns/{id}/resume:
    patch:
      description: Resume a stopped campaign.
      operationId: resumeCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Resume campaign
      tags:
      - Campaigns
  /campaigns/{id}/schedule:
    patch:
      description: Schedule the campaign launching.
      operationId: scheduleCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      - description: request body
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/v1.ScheduleRequest'
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Schedule campaign
      tags:
      - Campaigns
  /campaigns/{id}/start:
    patch:
      description: Launch the campaign immediately.
      operationId: startCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Start campaign
      tags:
      - Campaigns
  /campaigns/{id}/stats:
    get:
      description: |
        Get current statistics aggregation for the campaign.

        This will show current campaign status as well as amount of messages in each status. For each status detailed documentation, refer to [Apifonica Get message info](https://docs.apifonica.com/platform/#operation/getMessage) `status` field description.
      operationId: getCampaignStats
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignStatsResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Get campaign statistics
      tags:
      - Campaigns
  /campaigns/{id}/stop:
    patch:
      description: |-
        Pause the campaign temporarily.
        It can be resumed later using [Resume campaign](#operation/resumeCampaign).
      operationId: stopCampaign
      parameters:
      - description: campaign ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.CampaignResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Stop campaign
      tags:
      - Campaigns
  /contacts:
    post:
      description: |
        Create contacts that can be used later in campaigns.

        When creating contacts, there is normalization and filtering in place.

        ### Normalization
        - all non-numeric characters are removed, e.g. `+`, `()`, `-`, etc.
        - so, a number "+(358)94-200-00-00" becomes 358942000000

        ### Filtering
        - already existing or duplicated contacts will be skipped
        - invalid phone numbers will be skipped
        - landline numbers will be skipped (this behavior can be turned off, see request params below)

        ### Normalization with country code
        It is also possible to specify what country code the contacts belong to. For example, you may provide
        contacts in local phone number format, and specify the country for all of them. This behavior is regulated
        using `normalization_country_code` field in the request.
        - if `normalization_country_code` = `"RS"`, number "062-11-22-333" becomes "381621122333"
        - if `normalization_country_code` is empty, number "062-11-22-333" is filtered as invalid

        You will get the overview of what contacts were filtered in the response, see examples below.

        While creating contacts, you can specify associated labels and variables. Check [Contacts](#tag/Contacts) for more details.

        Check [Create Campaign](#operation/createCampaign) for more info on how to link campaign and contacts.
      operationId: createContacts
      parameters:
      - description: Create contacts with labels
        in: body
        name: request
        required: true
        schema:
          $ref: '#/definitions/v1.CreateContactsRequest'
      responses:
        "201":
          description: Created
          schema:
            $ref: '#/definitions/v1.CreateContactsResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Create contacts
      tags:
      - Contacts
  /reports:
    get:
      description: List all reports.
      operationId: listReports
      parameters:
      - description: Filter by Campaign ID
        example: 01961600-b921-7cc9-9849-000000000001
        in: query
        name: campaign_id
        type: string
      - description: |-
          Number of retrieved items per page.

          Default value is **20**.

          Maximum value is **100**.

          If provided limit is greater than maximum, a validation error will be returned.
        example: "10"
        in: query
        name: limit
        type: string
      - description: |-
          Pagination token that is used to retrieve the next page.

          See [Pagination](#section/Pagination) for more details.
        example: aWQ6MDE5NmVkMzEtYTEzMy03M2Y3LThmZjEtMDA5NmM5OWU4NmI3
        in: query
        name: next
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.ReportListResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: List reports
      tags:
      - Reports
  /reports/{id}:
    get:
      description: Get report by ID.
      operationId: getReport
      parameters:
      - description: report ID
        in: path
        name: id
        required: true
        type: string
      responses:
        "200":
          description: OK
          schema:
            $ref: '#/definitions/v1.ReportResponse'
        "400":
          description: Bad Request
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "403":
          description: Forbidden
          schema:
            $ref: '#/definitions/apierror.ErrorAPI'
        "404":
          description: Not Found
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
        "500":
          description: Internal Server Error
          schema:
            $ref: '#/definitions/v1.ErrorResponse'
      summary: Get report
      tags:
      - Reports
produces:
- application/json
schemes:
- https
swagger: "2.0"
tags:
- description: |
    Contacts are your customers or recipients of your messages. You can reuse contacts in your campaigns.

    ### Labels
    Labels serve the grouping/segmentation purpose.

    Every contact is associated with one or more labels (this happens during [contacts creation](#operation/createContacts)). For example, you may create one contact batch with "Retail customers" label, and another batch with "Wholesale customers" label. After that, you may use these labels in different campaigns to target different groups of customers.

    ### Variables
    Variables enable dynamic text substitution for each of your contacts.

    Each contact may have many variables. Variables are just simple key-value pairs. For example, you can have a contact with the following variables:
    ```json
    {
      "name": "Alex",
      "customer_id": "101"
    }
    ```

    Then, say in the SMS campaign, you can have the following message_template:
    ```json
    {
      "message_template": {
        "payload": {
          "text": "Hi {{ name }}, haven't seen you for a while on our website! Mind checking our newest offers? Follow this link - https://my-website.org/login?customer_id={{ customer_id }}"
        }
      }
    }
    ```

    This will result in the following message:

    > Hi **Alex**, haven't seen you for a while on our website! Mind checking our newest offers? Follow this link - **https://my-website.org/login?customer_id=101**

    Each variable must start with `{{` and end with `}}`. Variables themselves can only contain letters, numbers, underscores, and dashes (regex `[a-zA-Z0-9_-]`). Templates are validated - you will receive an error if the template is invalid.
  name: Contacts
- description: Campaigns management
  name: Campaigns
- description: Reports contain detailed statistics of your campaigns.
  name: Reports
