SendHub Group API

Create and manage groups.

Operations 7

GET /v1/groups List Groups #
POST /v1/groups Create Group #
GET /v1/groups/{group_id} Get Group #
PUT /v1/groups/{group_id} Update Group #
DELETE /v1/groups/{group_id} Delete Group #
GET /v1/groups/{group_id}/contacts List Group's Contacts #
POST /v1/groups/{group_id}/contacts Add/Remove Group's Contacts #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/sendhub-group-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

sendhub-group-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: SendHub Authentication Group API
  version: v1
  contact:
    name: Contact SendHub
    email: support@sendhub.com
  termsOfService: https://www.sendhub.com/terms/
  license:
    url: https://www.sendhub.com/terms/#:~:text=Limited%20License
    name: Limited
  description: 'SendHub''s REST-like API allows you to control & interact with your SendHub account programmatically.


    Note: this documentation is in Beta and may be updated periodically.'
servers:
- url: https://api.sendhub.com
  description: SendHub's API
security:
- username: []
  api_key: []
- basic_auth: []
tags:
- name: Group
  x-displayName: Groups
  description: Create and manage groups.
paths:
  /v1/groups:
    x-testConfig:
      enabled: true
    get:
      x-testConfig:
        params:
          limit: 1
      tags:
      - Group
      summary: List Groups
      description: Gets a list of groups
      operationId: listGroups
      parameters:
      - $ref: '#/components/parameters/PageLimit'
      - $ref: '#/components/parameters/PageOffset'
      responses:
        '200':
          $ref: '#/components/responses/listGroups200'
        '401':
          $ref: '#/components/responses/401'
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
    post:
      x-testConfig:
        body:
          name: jest test {{now()}}{{random()}}
      tags:
      - Group
      summary: Create Group
      description: Creates a group
      operationId: createGroup
      responses:
        '201':
          $ref: '#/components/responses/createGroup201'
        '400':
          $ref: '#/components/responses/updateGroup400'
        '401':
          $ref: '#/components/responses/401'
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
      requestBody:
        $ref: '#/components/requestBodies/createGroup'
  /v1/groups/{group_id}:
    x-testConfig:
      enabled: true
      pathParameters:
        group_id: '{{group_id}}'
    parameters:
    - in: path
      name: group_id
      required: true
      schema:
        type: string
      description: The group ID
    get:
      tags:
      - Group
      summary: Get Group
      description: Gets an individual group by its id
      operationId: getGroup
      responses:
        '200':
          $ref: '#/components/responses/getGroup200'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/group404'
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
    put:
      x-testConfig:
        body:
          id: '{{group_id}}'
          name: ACME Alerts
          slug: alerts
          text_to_subscribe: true
          ttjResponse: Thanks for opting in!\nOpt-out anytime by replying UNSUBSCRIBE ALERTS
      tags:
      - Group
      summary: Update Group
      description: 'Updates an individual group referenced by its id


        **Note:** this is a _replace_ operation; any properties the group already has that you don''t specify in your request will be set to their defaults'
      operationId: updateGroup
      responses:
        '200':
          $ref: '#/components/responses/updateGroup200'
        '400':
          $ref: '#/components/responses/updateGroup400'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/group404'
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
      requestBody:
        $ref: '#/components/requestBodies/updateGroup'
    delete:
      x-testConfig:
        enabled: false
      tags:
      - Group
      summary: Delete Group
      description: Deletes a group
      operationId: deleteGroup
      responses:
        '204':
          description: Deleted group
        '401':
          $ref: '#/components/responses/401'
        '404':
          description: Group not found
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
  /v1/groups/{group_id}/contacts:
    x-testConfig:
      enabled: true
      pathParameters:
        group_id: '{{group_id}}'
    parameters:
    - in: path
      name: group_id
      required: true
      schema:
        type: string
      description: The group ID
    get:
      x-testConfig:
        params:
          limit: 1
      tags:
      - Group
      summary: List Group's Contacts
      description: Lists contacts in a specified group
      operationId: listGroupContacts
      parameters:
      - $ref: '#/components/parameters/PageLimit'
      - $ref: '#/components/parameters/PageOffset'
      - $ref: '#/components/parameters/ContactsListFilterByNumber'
      - $ref: '#/components/parameters/ContactsListFilterByName'
      - $ref: '#/components/parameters/ContactsListFilterByScreened'
      - $ref: '#/components/parameters/ContactsListFilterByBlocked'
      - $ref: '#/components/parameters/ContactsListOrdering'
      responses:
        '200':
          $ref: '#/components/responses/listGroupContacts200'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/contact404'
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
    post:
      x-testConfig:
        body:
          add:
          - '116006957938017590'
      tags:
      - Group
      summary: Add/Remove Group's Contacts
      description: Add and/or remove contacts from a group
      operationId: addRemoveGroupContacts
      responses:
        '202':
          $ref: '#/components/responses/addRemoveGroupContacts202'
        '401':
          $ref: '#/components/responses/401'
        '404':
          $ref: '#/components/responses/contact404'
        '420':
          $ref: '#/components/responses/420PlanLimit'
        '429':
          $ref: '#/components/responses/429RateLimiting'
      requestBody:
        $ref: '#/components/requestBodies/addRemoveGroupContacts'
components:
  schemas:
    textToSubscribe:
      type: boolean
      default: false
      description: Whether to enable text-to-join functionality for this group
    group:
      type: object
      properties:
        date_created:
          $ref: '#/components/schemas/timestamp'
        date_modified:
          $ref: '#/components/schemas/timestamp'
        deleted:
          $ref: '#/components/schemas/deleted'
        id:
          $ref: '#/components/schemas/groupId'
        id_str:
          $ref: '#/components/schemas/idStr'
        is_shared:
          $ref: '#/components/schemas/isShared'
        name:
          $ref: '#/components/schemas/groupName'
        parent_id:
          $ref: '#/components/schemas/nullableString'
        parent_user_id:
          $ref: '#/components/schemas/nullableString'
        permissions:
          $ref: '#/components/schemas/groupPermissions'
        resource_uri:
          $ref: '#/components/schemas/groupResourceUri'
        share_invite_count:
          $ref: '#/components/schemas/nullableInteger'
        size:
          $ref: '#/components/schemas/groupSize'
        slug:
          $ref: '#/components/schemas/groupSlug'
        text_to_subscribe:
          $ref: '#/components/schemas/textToSubscribe'
        ttjResponse:
          $ref: '#/components/schemas/ttjResponse'
    addRemoveGroupContactsRequest:
      title: addRemoveGroupContactsRequest
      type: object
      oneOf:
      - allOf:
        - x-$ref: '#/components/schemas/addRemoveGroupContactsRequestAdd'
        - $ref: '#/components/schemas/addRemoveGroupContactsRequestAdd'
      - allOf:
        - x-$ref: '#/components/schemas/addRemoveGroupContactsRequestRemove'
        - $ref: '#/components/schemas/addRemoveGroupContactsRequestRemove'
      - allOf:
        - x-$ref: '#/components/schemas/addRemoveGroupContactsRequestBoth'
        - $ref: '#/components/schemas/addRemoveGroupContactsRequestBoth'
    rateLimitingResponse:
      properties:
        message:
          type: string
          example: You have sent too many requests.
        code:
          type: string
          pattern: ^\d+$
          example: '429'
        error:
          type: string
          example: Too Many Requests
        devMessage:
          type: string
        moreInfo:
          type: string
        timeLeft:
          type: string
          pattern: ^\d:[0-5]\d:[0-5]\d$
    id:
      type: string
      pattern: ^\d+$
    contactId:
      allOf:
      - $ref: '#/components/schemas/id'
      description: The contact ID
    groupSize:
      type:
      - integer
      - 'null'
      description: The number of contacts that are a memeber of this group
    idStr:
      type: string
      pattern: ^\d+$
      description: Same as id but always a string
    groupName:
      type: string
      description: The group's name
      minLength: 1
      maxLength: 128
    contactIdInt:
      type: integer
      format: int64
      description: The contact ID
    addRemoveGroupContactsRequestAdd:
      title: addRemoveGroupContactsRequestAdd
      type: object
      required:
      - add
      additionalProperties: false
      properties:
        add:
          type: array
          items:
            $ref: '#/components/schemas/contactIdBoth'
          description: Contact ids that you want to add to this group
    next:
      type:
      - string
      - 'null'
    nullableString:
      type:
      - string
      - 'null'
    customField:
      type:
      - string
      - 'null'
      description: 'Custom field(s)


        There''s no limit to the number or size of custom fields (this may be subject to change in the future) except for a total limit of 65,535 bytes for the string of the json object that they''re stored in


        **Note:** Custom fields may add *very* slight load time per contact. This is typically only noticable when listing many contacts that have a large amount of custom fields

        Note: Setting the value to `null` removes the custom field'
    screened:
      type: boolean
      description: Whether the contact has been blocked by you
    groupWithMediums:
      allOf:
      - $ref: '#/components/schemas/group'
      - properties:
          mediums:
            $ref: '#/components/schemas/groupMediums'
    previous:
      type:
      - string
      - 'null'
    nullableInteger:
      type:
      - integer
      - 'null'
    blocked:
      type: boolean
      description: Opt-out status (eg. if they texted `Stop`, `Cancel`, `Block`, `Quit` or `End` - [more info](https://sendhub.force.com/support/s/article/SendHub-Number-FAQ))
    createGroupRequest:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/groupName'
        is_shared:
          $ref: '#/components/schemas/isShared'
        slug:
          $ref: '#/components/schemas/groupSlug'
        mediums:
          $ref: '#/components/schemas/groupMediums'
        permissions:
          $ref: '#/components/schemas/groupPermissions'
        text_to_subscribe:
          $ref: '#/components/schemas/textToSubscribe'
        ttjResponse:
          $ref: '#/components/schemas/ttjResponse'
      required:
      - name
    timestamp:
      type: string
      description: 'A UTC timestamp


        `2021-08-01T03:48:55.350453` equals August 1st, 2021 at 3:48 and 55.350453 seconds AM (UTC)'
      example: '2021-08-01T03:48:55.350453'
      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{6}$
    contactIdBoth:
      type: string
      anyOf:
      - $ref: '#/components/schemas/contactId'
      - $ref: '#/components/schemas/contactIdInt'
    addRemoveGroupContacts202ResponseRemove:
      type: object
      properties:
        remove:
          type: array
          items:
            type: string
          description: Contact ids that failed to be removed from this group
    nameErrorObject:
      type: object
      properties:
        name:
          type: array
          items:
            type: string
    addRemoveGroupContacts202ResponseAdd:
      type: object
      properties:
        add:
          type: array
          items:
            type: string
          description: Contact ids that failed to be added to this group
    groupPermissions:
      allOf:
      - $ref: '#/components/schemas/nullableString'
      - default: write
        enum:
        - write
    contact:
      title: Contact
      type: object
      additionalProperties:
        $ref: '#/components/schemas/customField'
      properties:
        blocked:
          $ref: '#/components/schemas/blocked'
        deleted:
          $ref: '#/components/schemas/deleted'
        id_str:
          $ref: '#/components/schemas/idStr'
        is_owned:
          $ref: '#/components/schemas/isOwned'
        keyword:
          $ref: '#/components/schemas/contactKeyword'
        name:
          $ref: '#/components/schemas/contactName'
        number:
          $ref: '#/components/schemas/contactNumber'
        screened:
          $ref: '#/components/schemas/screened'
        id:
          $ref: '#/components/schemas/contactId'
        date_created:
          $ref: '#/components/schemas/timestamp'
        date_modified:
          $ref: '#/components/schemas/timestamp'
        local_gateway:
          $ref: '#/components/schemas/localGateway'
        resource_uri:
          $ref: '#/components/schemas/contactResourceUri'
        groups:
          $ref: '#/components/schemas/listOfGroupResourceUris'
        landline:
          $ref: '#/components/schemas/landline'
        landline_override:
          $ref: '#/components/schemas/landlineOverride'
      required:
      - name
      - number
    updateGroupRequest:
      allOf:
      - $ref: '#/components/schemas/createGroupRequest'
      - type: object
        properties:
          id:
            $ref: '#/components/schemas/contactId'
      required:
      - id
      - name
    addRemoveGroupContacts202Response:
      type: object
      properties:
        add:
          type: array
          items:
            $ref: '#/components/schemas/contactIdBoth'
          description: Contact ids successfully added to this group
        errors:
          anyOf:
          - $ref: '#/components/schemas/addRemoveGroupContacts202ResponseAdd'
          - $ref: '#/components/schemas/addRemoveGroupContacts202ResponseRemove'
          - allOf:
            - $ref: '#/components/schemas/addRemoveGroupContacts202ResponseAdd'
            - $ref: '#/components/schemas/addRemoveGroupContacts202ResponseRemove'
        remove:
          type: array
          items:
            $ref: '#/components/schemas/contactIdBoth'
          description: Contact ids successfully removed from this group
    contactNumber:
      type: string
      pattern: ^\+1\d{10}$
      description: The contact's phone number
    addRemoveGroupContactsRequestBoth:
      title: addRemoveGroupContactsRequestBoth
      type: object
      required:
      - add
      - remove
      properties:
        add:
          $ref: '#/components/schemas/addRemoveGroupContactsRequestAdd/properties/add'
        remove:
          $ref: '#/components/schemas/addRemoveGroupContactsRequestRemove/properties/remove'
    contactName:
      type: string
      description: The contact's name
      minLength: 1
      maxLength: 128
    errorObject:
      type: object
      properties:
        error:
          type: string
        status:
          type: number
    landline:
      type: boolean
      description: Whether SendHub has determined the contact's number is a landline number
    groupResourceUri:
      type: string
      pattern: ^\/v\d+(\.\d+)*\/groups\/\d+$
      description: Resource URI for this group
      example: /v1/groups/115999753870991332
    isShared:
      type: boolean
      description: Whether the group is shared between the lines
      deprecated: true
    listContacts200Response:
      title: listContacts200Response
      type: object
      properties:
        meta:
          $ref: '#/components/schemas/meta'
          x-$ref: '#/components/schemas/meta'
        objects:
          type: array
          items:
            $ref: '#/components/schemas/contact'
            x-$ref: '#/components/schemas/contact'
    ttjResponse:
      type: string
      maximum: 70
      default: You are now subscribed.
      description: A custom response sent when someone texts-to-join this group
    listGroups200Response:
      type: object
      properties:
        meta:
          $ref: '#/components/schemas/meta'
        objects:
          type: array
          items:
            $ref: '#/components/schemas/group'
    listOfGroupResourceUris:
      type: array
      items:
        $ref: '#/components/schemas/groupResourceUri'
      description: List of group resource URIs
    addRemoveGroupContactsRequestRemove:
      title: addRemoveGroupContactsRequestRemove
      type: object
      required:
      - remove
      additionalProperties: false
      properties:
        remove:
          type: array
          items:
            $ref: '#/components/schemas/contactIdBoth'
          description: Contact ids that you want to remove from this group
    offset:
      type: integer
    landlineOverride:
      type: boolean
      description: 'TODO: '
    contactResourceUri:
      type: string
      pattern: ^\/v\d+(\.\d+)*\/contacts\/\d+$
      description: Resource URI for this contact
      example: /v1/contacts/116006957938017590
    isOwned:
      type: boolean
      description: This is used internally and may be expanded upon or removed in the future
      readOnly: true
    localGateway:
      type: boolean
      description: True if the contact is a SendHub line
      readOnly: true
    limit:
      type: integer
    groupId:
      type: string
      allOf:
      - $ref: '#/components/schemas/id'
      description: The group ID
    meta:
      type: object
      properties:
        offset:
          $ref: '#/components/schemas/offset'
        limit:
          $ref: '#/components/schemas/limit'
        previous:
          $ref: '#/components/schemas/previous'
        next:
          $ref: '#/components/schemas/next'
    groupMediums:
      allOf:
      - $ref: '#/components/schemas/nullableString'
      - deprecated: true
        description: This is used internally and may be expanded upon or removed in the future
    groupSlug:
      type: string
      description: 'The "keyword" used to text-to-join


        Defaults to the group name lowercased, without any spaces and not duplicate by appending an incrementing number if needed'
    contactKeyword:
      type: string
      example: john
      description: 'The keyword must be unique and is generated by the contact''s name by default.

        [Learn more about how contact keywords are used here.](https://sendhub.force.com/support/s/article/contacts-faq)

        '
    deleted:
      type: boolean
      readOnly: true
  parameters:
    ContactsListFilterByNumber:
      name: number
      in: query
      description: "Filters contacts by their phone `number`\n  \nThe value _**must**_ be in the E.164 format and URI-encoded (eg. `+18004445555` would become `%2B18004445555`)"
      schema:
        type: string
      examples:
        Only show contacts with a `number` matching +18004445555:
          summary: Only show contacts with a `number` matching +18004445555
          value: '%2B18004445555'
        Only show contacts with a `number` matching +12015716227:
          summary: Only show contacts with a `number` matching +12015716227
          value: '%2B12015716227'
    PageOffset:
      name: offset
      in: query
      description: (Pagination) How many records to skip
      schema:
        type: integer
        default: 0
    ContactsListFilterByScreened:
      name: screened
      in: query
      description: Filters the contacts by their `screened` status (eg. if _**you**_ blocked them)
      schema:
        type: boolean
      examples:
        Only show contacts that you have blocked:
          summary: Only show contacts that you have blocked
          value: true
        Only show contacts that you haven't blocked:
          summary: Only show contacts that you haven't blocked
          value: false
    PageLimit:
      name: limit
      in: query
      description: (Pagination) How many records to return
      schema:
        type: integer
        maximum: 1000
        minimum: 1
        default: 20
    ContactsListOrdering:
      name: ordering
      in: query
      description: 'Sort contacts by a specified field (prepend a hyphen to reverse order)


        **Must** be a built-in contact field, not a custom field'
      schema:
        type: string
        enum:
        - name
        - -name
        - date_created
        - -date_created
        - date_modified
        - -date_modified
        - id
        - -id
        - blocked
        - -blocked
        - screened
        - -screened
        - is_owned
        - -is_owned
        - keyword
        - -keyword
        - number
        - -number
      examples:
        Sort contacts by date_created last-to-first:
          summary: Sort contacts by date_created last-to-first
          value: -date_created
        Sort contacts by date_created first-to-last:
          summary: Sort contacts by date_created first-to-last
          value: date_created
        Sort contacts by date_modified last-to-first:
          summary: Sort contacts by date_modified last-to-first
          value: -date_modified
        Sort contacts by date_modified first-to-last:
          summary: Sort contacts by date_modified first-to-last
          value: date_modified
        Sort contacts by their name Z-to-A:
          summary: Sort contacts by their name Z-to-A
          value: -name
        Sort contacts by their name A-to-Z:
          summary: Sort contacts by their name A-to-Z
          value: name
    ContactsListFilterByName:
      name: name
      in: query
      description: Filters contacts by their `name` (Will only return contacts whose name matches **exactly**)
      schema:
        type: string
      examples:
        John Smith:
          value: John Smith
        Bob Parker:
          value: Bob Parker
    ContactsListFilterByBlocked:
      name: blocked
      in: query
      description: Filters the contacts by opt-out status (eg. if they texted `Stop`, `Cancel`, `Block`, `Quit` or `End` - [more info](https://sendhub.force.com/support/s/article/SendHub-Number-FAQ))
      schema:
        type: boolean
      examples:
        Only show contacts that have opted-out:
          summary: Only show contacts that have opted-out
          value: true
        Only show contacts that haven't opted-out:
          summary: Only show contacts that haven't opted-out
          value: false
  examples:
    createGroupResponse1:
      summary: Example group 1
      value:
        date_created: '2021-08-24T19:44:31.266590'
        date_modified: '2021-08-24T19:44:31.266590'
        deleted: false
        id: '115999753870990933'
        id_str: '115999753870990933'
        is_shared: false
        name: ACME Product Alerts
        parent_id: null
        parent_user_id: null
        permissions: write
        resource_uri: /v1/groups/115999753870990933
        share_invite_count: null
        size: null
        slug: alerts
        text_to_subscribe: true
        ttjResponse: 'Thanks for opting in!

          Opt-out anytime by replying UNSUBSCRIBE ALERTS'
        mediums: null
    updateGroup2:
      summary: Example group 2
      value:
        date_created: '2021-08-24T19:44:31.266590'
        date_modified: '2021-08-24T19:44:31.266590'
        deleted: false
        id: '115999753870990932'
        id_str: '115999753870990932'
        is_shared: false
        name: New Leads
        parent_id: null
        parent_user_id: null
        permissions: write
        resource_uri: /v1/groups/115999753870990932
        share_invite_count: 0
        size: 1
        slug: leads
        text_to_subscribe: false
        ttjResponse: You are now subscribed.
        mediums: null
    Updating_a_group:
      summary: Updating a group
      value:
        id: '115999753870990933'
        name: ACME Product Alerts
    errorResponseMissingNameField:
      summary: Missing name field
      value:
        name:
        - This field is required.
    errorResponseTtjTooLong:
      summary: Text-to-join message is too long
      value:
        error: Join message can not be longer than 70 characters.
        status: 400
    getGroup200Response2:
      summary: Example group 2
      value:
        date_created: '2021-08-24T19:44:31.266590'
        date_modified: '2021-08-24T19:44:31.266590'
        deleted: false
        id: '115999753870990932'
        id_str: '115999753870990932'
        is_shared: false
        name: New Leads
        parent_id: null
        parent_user_id: null
        permissions: write
        resource_uri: /v1/groups/115999753870990932
        share_invite_count: 0
        size: 1
        slug: leads
        text_to_subscribe: false
        ttjResponse: You are now subscribed.
    listGroupContacts200Response:
      value:
        meta:
          limit: 20
          next: null
          offset: 0
          previous: null
        objects:
        - blocked: false
          date_created: '2021-08-24T19:44:31.266590'
          date_modified: '2021-08-24T19:44:31.266590'
          deleted: false
          groups: []
          id: '116006957938017590'
          id_str: '116006957938017590'
          is_owned: true
          keyword: bob
          local_gateway: false
          name: Bob Parker
          number: '+12015716227'
          resource_uri: /v1/contacts/116006957938017590
          screened: false
          landline: false
          landline_override: false
    Creating_a_group:
      summary: Creating a group
      value:
        name: ACME Product Alerts
    Creating_a_group_with_more_options:
      summary: Creating a group with more options
      value:
        name: ACME Product Alerts
        slug: alerts
        text_to_subscribe: true
        ttjResponse: 'Thanks for opting in!

          Opt-out anytime by replying UNSUBSCRIBE ALERTS'
    getGroup200Response1:
      summary: Example group 1
      value:
        date_created: '2021-08-24T19:44:31.266590'
        date_modified: '2021-08-24T19:44:31.266590'
        deleted: false
        id: '115999753870990933'
        id_str: '115999753870990933'
        is_shared: false
        name: ACME Product Alerts
        parent_id: null
        parent_user_id: null
        permissions: write
        resource_uri: /v1/groups/115999753870990933
        share_invite_count: 0
        size: 1
        slug: alerts
        text_to_subscribe: true
        ttjResponse: 'Thanks for opting in!

          Opt-out anytime by replying UNSUBSCRIBE ALERTS'
    createGroupResponse2:
      summary: Example group 2
      value:
        date_created: '2021-08-24T19:44:31.266590'
        date_modified: '2021-08-24T19:44:31.266590'
        deleted: false
        id: '115999753870990932'
        id_str: '115999753870990932'
        is_shared: false
        name: New Leads
        parent_id: null
        parent_user_id: null
        permissions: write
        resource_uri: /v1/groups/115999753870990932
        share_invite_count: null
        size: null
        slug: leads
        text_to_subscribe: false
        ttjResponse: You are now subscribed.
        mediums: null
    Updating_a_group_with_more_options:
      summary: Updating a group with more options
      value:
        id: '115999753870990933'
        name: ACME Product Alerts
        slug: alerts
        text_to_subscribe: true
        ttjResponse: 'Thanks for opting in!

          Opt-out anytime by replying UNSUBSCRIBE ALERTS'
    listGroups200Response:
      value:
        meta:
          limit: 20
          next: null
          offset: 0
          previous: null
        objects:
        - date_created: '2021-08-24T19:44:31.266590'
          date_modified: '2021-08-24T19:44:31.266590'
          deleted: false
          id: '115999753870990933'
          id_str: '115999753870990933'
          is_shared: false
          name: ACME Product Alerts
          parent_id: null
          parent_user_id: null
          permissions: write
          resource_uri: /v1/groups/115999753870990933
          share_invite_count: 0
          size: 1
          slug: alerts
          text_to_subscribe: true
          ttjResponse: 'Thanks for opting in!

            Opt-out anytime by replying UNSUBSCRIBE ALERTS'
        - date_created: '2021-08-24T19:44:31.266590'
          date_modified: '2021-08-24T19:44:31.266590'
          deleted: false
          id: '115999753870990932'
          id_str: '115999753870990932'
          is_shared: false
          name: New Leads
          parent_id: null
          parent_user_id: null
          permissions: write
          resource_uri: /v1/groups/115999753870990932
          share_invite_count: 0
          size: 1
          slug: leads
          text_to_subscribe: false
          ttjResponse: You are now subscribed.
    updateGroup1:
      summary: Example group 1
      value:
        date_created: '2021-08-24T19:44:31.266590'
        date_modified: '2021-08-24T19:44:31.266590'
        deleted: false
        id: '115999753870990933'
        id_str: '115999753870990933'
        is_shared: false
        name: ACME Product Alerts
        parent_id: null
        parent_user_id: null
        permissions: write
        resource_uri: /v1/groups/115999753870990933
        share_invite_count: 0
        size: 1
        slug: alerts
        text_to_subscribe: true
        ttjResponse: 'Thanks for opting in!

          Opt-out anytime by replying UNSUBSCRIBE ALERTS'
        mediums: null
  responses:
    420PlanLimit:
      description: You've reached your plan's API limit for this month or you're on a plan that doesn't include API access
      content:
        application/json:
          schema:
            properties:
              error:
                type: string
          examples:
            You've reached your plan's API limit for this month or you're on a plan that doesn't include API access:
              summary: You've reached your plan's API limit for this month or you're on a plan that doesn't include API access
              value:
                error: You have made too many requests and are being rate limited
    listGroupContacts200:
      description: Success
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/listContacts200Response'
          examples:
            success:
              $ref: '#/components/examples/listGroupContacts200Response'
    contact404:
      description: Contact not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/errorObject'
          examples:
            Contact not found:
              summary: Contact not found
              value:
                error: Requested contact not found
                status: 404
    updateGroup200:
      description: Updated group
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/groupWithMediums'
          examples:
            Example group 1:
              $ref: '#/components/examples/updateGroup1'
            Example group 2:
              $ref: '#/components/examples/updateGroup2'
    '401':
      description: The credentials you supplied are invalid
    updateGroup400:
      description: Bad Request
      content:
        application/json:
          schema:
            anyOf:
            - $ref: '#/components/schemas/errorObject'
            - $ref: '#/components/schemas/nameErrorObject'
          examples:
            Missing Name Field:
              $ref: '#/components/examples/errorResponseMissingNameField'
            Missing id field or incorrect id provided:
              summary: Missing id field or incorrect id provided
              value:
                name:
                - Duplicate group name.
            Text-to-join message is too long:
              $ref: '#/components/examples/errorResponseTtjTooLong'
    createGroup201:
      description: Created group
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/groupWithMediums'


# --- truncated at 32 KB (37 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/sendhub/refs/heads/main/openapi/sendhub-group-api-openapi.yml