Reonic Contacts API

External people you interact with, such as customers or leads. Not to be confused with [**Users**](#tag/users), which represent members of your workspace.

OpenAPI Specification

reonic-contacts-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  title: Reonic REST Api v3 Activities Contacts API
  description: 'The Reonic REST API v3 provides programmatic access to create and manage resources. The API follows REST principles and returns responses in JSON format. Authentication is required via an API key passed in the X-Authorization header.


    ## Errors


    All endpoints return errors with the same JSON shape:


    ```json

    { "message": "human-readable description" }

    ```


    `400` responses additionally include an `errors` field with per-field validation details.


    The HTTP status code identifies the cause:


    | Status  | Meaning | When |

    |--------|---------|------|

    | `400` | Bad Request | Path params, query string, or request body failed validation. Inspect `errors` for the field-level breakdown. |

    | `401` | Unauthorized | The `X-Authorization` header is missing, malformed, does not match an active API key, or belongs to a different API version. The response never indicates which check failed; check that the key matches the endpoint version. API v3 endpoints require a v3 key with the `rnc_v3_` prefix. |

    | `403` | Forbidden | The API key is read-only and the request targeted a write endpoint (`POST`). Issue a key with write access. |

    | `404` | Not Found | A resource referenced by a path id does not exist or is not visible to your workspace. |

    | `429` | Too Many Requests | The per-client rate limit was exceeded. See **Rate limiting** below. |

    | `500` | Internal Server Error | Unexpected failure. Safe to retry once; if it persists, contact support. |

    | `503` | Service Unavailable | A backing dependency is temporarily unavailable. Retry with exponential backoff. |


    ## Rate limiting


    Limits are shared across all API keys you hold and reset on a 1-minute window. Two buckets:


    | Bucket | Limit | Applies to |

    |--------|-------|------------|

    | `cached` | 500 / min | `GET` requests served from the response cache |

    | `uncached` | 30 / min | Cache misses, `GET` requests sent with `Reonic-Cache-Control: no-cache`, and all `POST` requests |


    Every response includes:


    - `X-RateLimit-Bucket` — `cached` or `uncached`

    - `X-RateLimit-Limit` — the bucket''s ceiling (`500` or `30`)

    - `X-RateLimit-Remaining` — calls left in the current window

    - `X-RateLimit-Reset` — Unix epoch seconds at which the window resets

    - `X-RateLimit-Policy` — `<limit>;w=60`


    `429` responses additionally set `Retry-After` (in seconds). Wait at least that long before retrying.


    ## Caching and Reonic-Cache-Control


    `GET` responses are cached for up to 1 hour. Identical requests (same path and query) on the same API key return the cached result. To force a fresh read, send `Reonic-Cache-Control: no-cache`; the response is then refreshed and re-cached. Forced refreshes count against the `uncached` rate-limit bucket.


    The standard `Cache-Control` header is not honored. Use `Reonic-Cache-Control` to control caching behavior.


    ## Authentication


    Every request must include your API key in the `X-Authorization` header:


    ```

    X-Authorization: <your-api-key>

    ```


    API keys are issued from the Reonic web app and look like `rnc_v3_…`. Send the full value, including the prefix.

    '
  version: 3.2.0
  contact:
    email: kontakt@reonic.de
    url: https://reonic.com
    name: Reonic GmbH
servers:
- url: '{apiBaseUrl}/rest/v3/'
security:
- X-Authorization: []
tags:
- name: Contacts
  description: External people you interact with, such as customers or leads. Not to be confused with [**Users**](#tag/users), which represent members of your workspace.
paths:
  /contacts:
    get:
      summary: List contacts
      description: 'List contacts for the authenticated client in a paginated format.


        **Allowed API keys:** Read-only, Read and Write'
      tags:
      - Contacts
      parameters:
      - schema:
          type: string
          format: email
          description: Return only contacts whose primary or secondary email equals this address (case-insensitive exact match). Useful for matching an incoming email to a contact.
          example: jane.doe@example.com
        required: false
        description: Return only contacts whose primary or secondary email equals this address (case-insensitive exact match). Useful for matching an incoming email to a contact.
        name: email
        in: query
      - schema:
          type: string
          pattern: ^\+[1-9]\d{1,14}$
          description: Return only contacts whose phone or mobile number exactly matches this number. Must be in E.164 format (e.g. +491511234567). Useful for matching an incoming call to a contact. Numbers not stored in E.164 format cannot be matched by this filter.
          example: '+491511234567'
        required: false
        description: Return only contacts whose phone or mobile number exactly matches this number. Must be in E.164 format (e.g. +491511234567). Useful for matching an incoming call to a contact. Numbers not stored in E.164 format cannot be matched by this filter.
        name: phoneNumber
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Filter records where createdAt is after this datetime (exclusive)
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Filter records where createdAt is after this datetime (exclusive)
        name: createdAt.gt
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Filter records where createdAt is before this datetime (exclusive)
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Filter records where createdAt is before this datetime (exclusive)
        name: createdAt.lt
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Filter records where updatedAt is after this datetime (exclusive)
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Filter records where updatedAt is after this datetime (exclusive)
        name: updatedAt.gt
        in: query
      - schema:
          type:
          - string
          - 'null'
          format: date-time
          description: Filter records where updatedAt is before this datetime (exclusive)
          example: '2026-01-01T15:30:00.000Z'
        required: false
        description: Filter records where updatedAt is before this datetime (exclusive)
        name: updatedAt.lt
        in: query
      - schema:
          type: integer
          minimum: 1
          default: 1
          description: 'Page number, starting from 1. Default: 1.'
        required: false
        description: 'Page number, starting from 1. Default: 1.'
        name: page
        in: query
      - schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
          description: 'Number of items per page. Default: 50. Max: 200.'
        required: false
        description: 'Number of items per page. Default: 50. Max: 200.'
        name: itemsPerPage
        in: query
      - schema:
          type:
          - string
          - 'null'
          default: -createdAt
          description: 'Sort order. Use field names for ascending (e.g. "createdAt"), minus sign for descending (e.g. "-createdAt"). Chain with commas (e.g. "createdAt,editedAt"). Sortable fields: fullName, createdAt. Defaults to -createdAt.'
          examples:
          - -createdAt
          - createdAt,-fullName
        required: false
        description: 'Sort order. Use field names for ascending (e.g. "createdAt"), minus sign for descending (e.g. "-createdAt"). Chain with commas (e.g. "createdAt,editedAt"). Sortable fields: fullName, createdAt. Defaults to -createdAt.'
        name: sort
        in: query
      - schema:
          type: string
          example: no-cache
        required: false
        name: Reonic-Cache-Control
        in: header
        description: Set to 'no-cache' to bypass the 1-hour response cache and force a fresh read. The fresh response is then written back to the cache for subsequent callers. Forced refreshes count against the uncached rate-limit bucket (30/min); only cache hits count against the cached bucket (500/min).
      responses:
        '200':
          description: Paginated list of contacts
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Contact'
                  pagination:
                    type: object
                    properties:
                      page:
                        type: integer
                        minimum: 1
                        description: Current page number
                      perPage:
                        type: integer
                        minimum: 1
                        description: Number of items per page
                      total:
                        type: integer
                        minimum: 0
                        description: Total number of items across all pages
                      totalPages:
                        type: integer
                        minimum: 1
                      next:
                        type:
                        - string
                        - 'null'
                        description: Path to the next page, or null if there is no next page
                      prev:
                        type:
                        - string
                        - 'null'
                        description: Path to the previous page, or null if there is no previous page
                    required:
                    - page
                    - perPage
                    - total
                    - totalPages
                    - next
                    - prev
                required:
                - data
                - pagination
  /contacts/{contactId}:
    get:
      summary: Get contact
      description: 'Get a single contact by its ID.


        **Allowed API keys:** Read-only, Read and Write'
      tags:
      - Contacts
      parameters:
      - schema:
          type: string
          format: uuid
        required: true
        name: contactId
        in: path
      - schema:
          type: string
          example: no-cache
        required: false
        name: Reonic-Cache-Control
        in: header
        description: Set to 'no-cache' to bypass the 1-hour response cache and force a fresh read. The fresh response is then written back to the cache for subsequent callers. Forced refreshes count against the uncached rate-limit bucket (30/min); only cache hits count against the cached bucket (500/min).
      responses:
        '200':
          description: The contact
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactDetail'
  /contacts/create:
    post:
      summary: Create contact
      description: 'Create a new contact.


        **Allowed API keys:** Read and Write, Lead creation only'
      tags:
      - Contacts
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactCreate'
      responses:
        '201':
          description: The created contact
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactDetail'
  /contacts/{contactId}/update:
    post:
      summary: Update contact
      description: 'Update a contact by its ID.


        **Allowed API keys:** Read and Write'
      tags:
      - Contacts
      parameters:
      - schema:
          type: string
          format: uuid
        required: true
        name: contactId
        in: path
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                firstName:
                  type: string
                  minLength: 1
                  maxLength: 1000
                lastName:
                  type: string
                  minLength: 1
                  maxLength: 1000
                salutation:
                  type:
                  - string
                  - 'null'
                  enum:
                  - Female
                  - Male
                  - Diverse
                  - Family
                  - Business
                  - null
                primaryEmail:
                  type:
                  - string
                  - 'null'
                  maxLength: 1000
                  format: email
                secondaryEmail:
                  type:
                  - string
                  - 'null'
                  maxLength: 1000
                  format: email
                  description: Alternative email address
                mobile:
                  type:
                  - string
                  - 'null'
                  maxLength: 100
                  description: Mobile phone number
                phone:
                  type:
                  - string
                  - 'null'
                  maxLength: 100
                  description: Landline phone number
                phoneReachability:
                  type:
                  - string
                  - 'null'
                  enum:
                  - Morning
                  - Afternoon
                  - Evening
                  - Fulltime
                  - WeekendOnly
                  - EmailOnly
                  - null
                address:
                  type: object
                  properties:
                    street:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                    houseNumber:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                    city:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                    postcode:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                    country:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                  additionalProperties: false
                integrations:
                  type: object
                  properties:
                    bitrixId:
                      type:
                      - integer
                      - 'null'
                      minimum: 1
                      maximum: 9007199254740991
                    hubspotId:
                      type:
                      - string
                      - 'null'
                      format: uuid
                    pdsId:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                    photovateId:
                      type:
                      - string
                      - 'null'
                      maxLength: 1000
                    pipedriveId:
                      type:
                      - integer
                      - 'null'
                      minimum: 1
                      maximum: 9007199254740991
                    weclappId:
                      type:
                      - string
                      - 'null'
                      format: uuid
                  additionalProperties: false
                  description: IDs of this contact in third-party systems
              additionalProperties: false
      responses:
        '200':
          description: The updated contact
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactDetail'
        '404':
          description: Contact not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                required:
                - message
components:
  schemas:
    ContactDetail:
      allOf:
      - $ref: '#/components/schemas/Contact'
      - type: object
        properties:
          commercialProjectIds:
            type: array
            items:
              type: string
              format: uuid
            description: IDs of commercial projects associated with this contact
            example:
            - 123e4567-e89b-12d3-a456-426614174000
          residentialProjectIds:
            type: array
            items:
              type: string
              format: uuid
            description: IDs of residential projects associated with this contact
            example:
            - 123e4567-e89b-12d3-a456-426614174000
          marketingConsent:
            type: boolean
            description: Whether the contact has given marketing consent
          marketingConsentText:
            type:
            - string
            - 'null'
          marketingConsentDataProtectionLink:
            type:
            - string
            - 'null'
          utm:
            type: object
            properties:
              campaign:
                type:
                - string
                - 'null'
              content:
                type:
                - string
                - 'null'
              medium:
                type:
                - string
                - 'null'
              source:
                type:
                - string
                - 'null'
              term:
                type:
                - string
                - 'null'
            required:
            - campaign
            - content
            - medium
            - source
            - term
            description: UTM parameters associated with this contact
          integrations:
            type: object
            properties:
              bitrixId:
                type:
                - number
                - 'null'
              hubspotId:
                type:
                - string
                - 'null'
                format: uuid
              pdsId:
                type:
                - string
                - 'null'
              photovateId:
                type:
                - string
                - 'null'
              pipedriveId:
                type:
                - number
                - 'null'
              weclappId:
                type:
                - string
                - 'null'
                format: uuid
            required:
            - bitrixId
            - hubspotId
            - pdsId
            - photovateId
            - pipedriveId
            - weclappId
            description: IDs of the contact in integrated third-party systems
        required:
        - commercialProjectIds
        - residentialProjectIds
        - marketingConsent
        - marketingConsentText
        - marketingConsentDataProtectionLink
        - utm
        - integrations
    Contact:
      type: object
      properties:
        id:
          type: string
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        fullName:
          type: string
          description: First and last name combined
        firstName:
          type: string
        lastName:
          type: string
        salutation:
          type:
          - string
          - 'null'
          enum:
          - Female
          - Male
          - Diverse
          - Family
          - Business
          - null
        primaryEmail:
          type:
          - string
          - 'null'
        secondaryEmail:
          type:
          - string
          - 'null'
          description: Alternative email address
        mobile:
          type:
          - string
          - 'null'
          description: Mobile phone number
        phone:
          type:
          - string
          - 'null'
          description: Landline phone number
        phoneReachability:
          type:
          - string
          - 'null'
          enum:
          - Morning
          - Afternoon
          - Evening
          - Fulltime
          - WeekendOnly
          - EmailOnly
          - null
        address:
          type: object
          properties:
            street:
              type:
              - string
              - 'null'
            houseNumber:
              type:
              - string
              - 'null'
            city:
              type:
              - string
              - 'null'
            postcode:
              type:
              - string
              - 'null'
            country:
              type:
              - string
              - 'null'
          required:
          - street
          - houseNumber
          - city
          - postcode
          - country
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
          description: Last edited date
        deletedAt:
          type:
          - string
          - 'null'
          format: date-time
      required:
      - id
      - fullName
      - firstName
      - lastName
      - salutation
      - primaryEmail
      - secondaryEmail
      - mobile
      - phone
      - phoneReachability
      - address
      - createdAt
      - updatedAt
      - deletedAt
    ContactCreate:
      type: object
      properties:
        firstName:
          type: string
          minLength: 1
          maxLength: 1000
        lastName:
          type: string
          minLength: 1
          maxLength: 1000
        salutation:
          type:
          - string
          - 'null'
          enum:
          - Female
          - Male
          - Diverse
          - Family
          - Business
          - null
        primaryEmail:
          type:
          - string
          - 'null'
          maxLength: 1000
          format: email
        secondaryEmail:
          type:
          - string
          - 'null'
          maxLength: 1000
          format: email
          description: Alternative email address
        mobile:
          type:
          - string
          - 'null'
          maxLength: 100
          description: Mobile phone number
        phone:
          type:
          - string
          - 'null'
          maxLength: 100
          description: Landline phone number
        phoneReachability:
          type:
          - string
          - 'null'
          enum:
          - Morning
          - Afternoon
          - Evening
          - Fulltime
          - WeekendOnly
          - EmailOnly
          - null
        address:
          type: object
          properties:
            street:
              type:
              - string
              - 'null'
              maxLength: 1000
            houseNumber:
              type:
              - string
              - 'null'
              maxLength: 1000
            city:
              type:
              - string
              - 'null'
              maxLength: 1000
            postcode:
              type:
              - string
              - 'null'
              maxLength: 1000
            country:
              type:
              - string
              - 'null'
              maxLength: 1000
          additionalProperties: false
        marketingConsent:
          type: boolean
          description: Whether the contact has given marketing consent
        marketingConsentText:
          type:
          - string
          - 'null'
          maxLength: 10000
        marketingConsentDataProtectionLink:
          type:
          - string
          - 'null'
          maxLength: 2000
        utm:
          type: object
          properties:
            campaign:
              type:
              - string
              - 'null'
              maxLength: 1000
            content:
              type:
              - string
              - 'null'
              maxLength: 1000
            medium:
              type:
              - string
              - 'null'
              maxLength: 1000
            source:
              type:
              - string
              - 'null'
              maxLength: 1000
            term:
              type:
              - string
              - 'null'
              maxLength: 1000
          additionalProperties: false
          description: UTM parameters associated with this contact
        integrations:
          type: object
          properties:
            bitrixId:
              type:
              - integer
              - 'null'
              minimum: 1
              maximum: 9007199254740991
            hubspotId:
              type:
              - string
              - 'null'
              format: uuid
            pdsId:
              type:
              - string
              - 'null'
              maxLength: 1000
            photovateId:
              type:
              - string
              - 'null'
              maxLength: 1000
            pipedriveId:
              type:
              - integer
              - 'null'
              minimum: 1
              maximum: 9007199254740991
            weclappId:
              type:
              - string
              - 'null'
              format: uuid
          additionalProperties: false
          description: IDs of this contact in third-party systems
      required:
      - firstName
      - lastName
      - marketingConsent
      additionalProperties: false
  securitySchemes:
    X-Authorization:
      type: apiKey
      in: header
      name: X-Authorization
x-tagGroups:
- name: People
  tags:
  - Contacts
  - Users
  - Teams
- name: Projects
  tags:
  - Residential Projects
  - Commercial Projects
- name: Working on a project
  tags:
  - Notes
  - Tasks
  - Files
  - File Folders
  - Activities
  - Time Tracking
  - Checklists
  - Checklist Templates
  - Signature Requests
- name: Calendar
  tags:
  - Calendars
  - Calendar Categories
  - Appointments
- name: Catalog
  tags:
  - Components
  - Planning Templates
  - Planning Packages
  - Offer Templates
- name: Workspace setup
  tags:
  - Kanban Boards
  - Kanban Columns
  - Tags
  - Lead Sources
- name: Wiki
  tags:
  - Wiki
- name: Services
  tags:
  - Photogrammetry
- name: API helpers
  tags:
  - Upload
  - Links
- name: Integrations
  tags:
  - Webhooks
- name: Guides
  tags:
  - Migrating from API v2 to v3
  - Changelog