osis-co Lines API

The Lines API from osis-co — 6 operation(s) for lines.

Operations 8

GET /lines List available dedicated lines #
POST /lines/claim Claim an available dedicated line #
POST /lines/{e164}/lock Lock a dedicated line for porting #
DELETE /lines/{e164}/lock Cancel number replacement setup #
GET /lines/{e164}/port Get port status #
POST /lines/{e164}/port Submit a port #
GET /lines/{id}/location Read a shared location #
POST /lines/{e164}/number-changes Change a dedicated phone number #

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/osis-co:osis-co-lines-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 form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

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

OpenAPI Specification

osis-co-lines-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Comms Lines API
  version: 1.0.0
  description: 'Send and receive texts, place and answer calls, and create payment requests from your Comms workspace. Base URL: `https://osis.co/api/v1/comms`. The Payments API has to be turned on for your workspace first.'
servers:
- url: https://osis.co/api/v1/comms
  description: Production
- url: https://comms.osis.co/api/v1/comms
  description: Comms host alias
security:
- bearerAuth: []
tags:
- name: Lines
paths:
  /lines:
    get:
      operationId: listAvailableDedicatedLines
      summary: List available dedicated lines
      description: 'See which dedicated numbers you can claim. This has to be turned on for your workspace, or you get 403 line_claim_not_allowed. Scope: `comms_lines_read`.'
      responses:
        '200':
          description: Available lines
          content:
            application/json:
              schema:
                type: object
                properties:
                  lines:
                    type: array
                    items:
                      type: object
                      properties:
                        e164:
                          type: string
                        status:
                          type: string
                        capabilities:
                          type: object
                          properties:
                            imessage:
                              type: boolean
                            sms:
                              type: boolean
                            sms_fallback:
                              type: boolean
                            attachments:
                              type: boolean
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      tags:
      - Lines
  /lines/claim:
    post:
      operationId: claimDedicatedLine
      summary: Claim an available dedicated line
      description: 'Add a dedicated number to your workspace. Messages to it come to you through the API and webhooks. This has to be turned on for your workspace, or you get 403 line_claim_not_allowed. Scope: `comms_lines_write`.'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                e164:
                  type: string
                  description: The number to claim, in E.164 format. Leave it out to get the next free number.
      responses:
        '200':
          description: Line claimed
          content:
            application/json:
              schema:
                type: object
                properties:
                  e164:
                    type: string
                  inbound_mode:
                    type: string
                    enum:
                    - api
                    - agent
                  status:
                    type: string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
      tags:
      - Lines
  /lines/{e164}/lock:
    post:
      operationId: lockDedicatedLine
      summary: Lock a dedicated line for porting
      description: 'Prepare a dedicated line for a number transfer. This does not submit a carrier request or change service. Cancel the preparation with DELETE on this path before submitting the port. Shared lines cannot be prepared. Requires porting access and comms_lines_write. Limit: 5 requests every 15 minutes per line.'
      parameters:
      - name: e164
        in: path
        required: true
        schema:
          type: string
        description: The dedicated line, in E.164 format and URL-encoded (+ becomes %2B, like %2B12025550123).
      responses:
        '201':
          description: Line locked
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinePortResponse'
        '400':
          description: The line is shared, not dedicated, or the number isn't valid E.164
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Porting isn't enabled for this workspace, or your key is missing the scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                permission_denied:
                  summary: Porting is not enabled for this workspace
                  value:
                    error: permission_denied
                    code: permission_denied
                    reason: org_not_allowed_for_port
                missing_scope:
                  summary: Key is missing the scope
                  value:
                    error: missing comms_lines_write scope
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: The line is already locked (`line_already_locked`), or the line can't be ported right now. Check `code`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                line_already_locked:
                  summary: Line already locked
                  value:
                    error: line_already_locked
                    code: line_already_locked
                    status: number_locked
        '429':
          $ref: '#/components/responses/RateLimited'
      tags:
      - Lines
    delete:
      operationId: cancelLinePortSetup
      summary: Cancel number replacement setup
      description: 'Cancel only an unsubmitted preparation (number_locked), without changing service or contacting the carrier. Supply the current port.id to avoid canceling a newer setup. Submitted, in-progress, completed, and failed transfer records cannot be canceled here. Scope: comms_lines_write. Limit: 10 requests every 15 minutes per line.'
      parameters:
      - name: e164
        in: path
        required: true
        schema:
          type: string
        description: The dedicated line, in E.164 format and URL-encoded (+ becomes %2B, like %2B12025550123).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - port_id
              properties:
                port_id:
                  type: string
                  description: Current preparation ID from POST /lock or GET /port
                  example: lport_0123456789abcdef
      responses:
        '200':
          description: Preparation canceled; current number and service unchanged
          content:
            application/json:
              schema:
                type: object
                properties:
                  cancelled:
                    type: boolean
                    enum:
                    - true
        '400':
          description: Invalid or missing port_id
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: No matching preparation in this workspace
        '409':
          description: Setup changed or a transfer was already submitted
        '429':
          $ref: '#/components/responses/RateLimited'
      tags:
      - Lines
  /lines/{e164}/port:
    get:
      operationId: getLinePort
      summary: Get port status
      description: 'Shows the port''s status, times, and errors. The account details you sent are never returned. Returns 404 port_not_found when the line has no port record or porting isn''t turned on for your workspace. Scope: comms_lines_read or comms_lines_write.'
      parameters:
      - name: e164
        in: path
        required: true
        schema:
          type: string
        description: The dedicated line, in E.164 format and URL-encoded (+ becomes %2B, like %2B12025550123).
      responses:
        '200':
          description: Port status
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinePortResponse'
        '400':
          description: The path isn't a valid US number in E.164 format (`invalid_line_e164` or `us_numbers_only`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Your key is missing the comms_lines_read scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                missing_scope:
                  summary: Key is missing the scope
                  value:
                    error: missing comms_lines_read scope
        '404':
          description: No port record for this line in your workspace (`port_not_found`)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                port_not_found:
                  summary: No port record
                  value:
                    error: port_not_found
                    code: port_not_found
      tags:
      - Lines
    post:
      operationId: startLinePort
      summary: Submit a port
      description: 'Transfer an existing number onto a prepared dedicated line. Contact support to turn on porting, and set authorized to true. After a carrier rejection you can fix the details and submit again. A line can''t have two active or completed transfers. Carrier credentials are encrypted and never returned. Scope: comms_lines_write. Limits: 3 a day per line and 10 a day per workspace. A body that fails schema validation (invalid_body) doesn''t count toward these limits; other 400s do.'
      parameters:
      - name: e164
        in: path
        required: true
        schema:
          type: string
        description: The dedicated line, in E.164 format and URL-encoded (+ becomes %2B, like %2B12025550123).
      - name: Idempotency-Key
        in: header
        required: false
        schema:
          type: string
        description: Lets you retry without sending twice.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartPortRequest'
      responses:
        '201':
          description: Port submitted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinePortResponse'
        '400':
          description: Something in the body is wrong
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Porting isn't enabled for this workspace, or your key is missing the scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                permission_denied:
                  summary: Porting is not enabled for this workspace
                  value:
                    error: permission_denied
                    code: permission_denied
                    reason: org_not_allowed_for_port
                missing_scope:
                  summary: Key is missing the scope
                  value:
                    error: missing comms_lines_write scope
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: The line isn't prepared, the preparation changed, a transfer was already submitted, the idempotency key was reused with a different body, the line can't be ported right now, or the target number is already in use. Check `code`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              examples:
                port_already_submitted:
                  summary: Transfer already submitted
                  value:
                    error: port_already_submitted
                    code: port_already_submitted
                    status: port_submitted
                port_setup_changed:
                  summary: Stale port_id
                  value:
                    error: Replacement setup has changed. Refresh and try again.
                    code: port_setup_changed
        '429':
          $ref: '#/components/responses/RateLimited'
      tags:
      - Lines
  /lines/{id}/location:
    get:
      operationId: getSharedLocation
      summary: Read a shared location
      description: Requires comms_read and access to the dedicated line. Returns a contact location only while they are sharing it with this number. Unsupported lines return 409. Responses are not cached.
      tags:
      - Lines
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: from
        in: query
        required: true
        schema:
          type: string
          pattern: ^\+[1-9]\d{7,14}$
        description: Contact E.164 phone number; encode the plus sign as %2B.
      responses:
        '200':
          description: Current sharing status and latest available shared point.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedLocation'
        '400':
          description: Invalid contact number.
        '401':
          description: Authentication required.
        '403':
          description: Missing scope or line ownership.
        '404':
          description: Line not found within this key’s access.
        '409':
          description: Location sharing is unsupported on this line.
        '429':
          description: Rate limit exceeded.
        '502':
          description: Invalid location response.
        '503':
          description: Location state cannot be verified.
  /lines/{e164}/number-changes:
    post:
      summary: Change a dedicated phone number
      operationId: startNumberChange
      description: 'Scope: comms_lines_write. Requires a paid dedicated line; contact support to turn this on. Gets a new number and switches routing once it''s ready for messaging. Exact area codes are best effort: a mismatch fails without switching.'
      parameters:
      - in: path
        name: e164
        required: true
        schema:
          type: string
        description: The owned US number to replace, URL-encoded.
      - in: header
        name: Idempotency-Key
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
              - area_code
              properties:
                area_code:
                  type: string
                  pattern: ^[2-9][0-9]{2}$
                require_exact_area_code:
                  type: boolean
                  default: true
      responses:
        '202':
          description: Saved number-change operation. Use the new number only after completed.
          content:
            application/json:
              schema:
                type: object
                required:
                - change
                properties:
                  change:
                    $ref: '#/components/schemas/NumberChange'
        '200':
          description: This idempotent operation already completed.
          content:
            application/json:
              schema:
                type: object
                required:
                - change
                properties:
                  change:
                    $ref: '#/components/schemas/NumberChange'
        '400':
          description: Invalid request or unsupported US area code.
        '402':
          description: A paid dedicated-line entitlement is required.
        '403':
          description: Missing scope, or number changes aren't turned on for this workspace.
        '404':
          description: The caller does not own this number.
        '409':
          description: Another operation owns this number, or the idempotency payload changed.
        '429':
          description: Workspace daily request limit reached.
      tags:
      - Lines
components:
  schemas:
    LinePortStatus:
      type: string
      description: Where the port is right now.
      enum:
      - number_locked
      - port_submitted
      - port_in_progress
      - port_completed
      - port_failed
    LnpFields:
      type: object
      description: Details from your current carrier. They must match the carrier's records exactly. You can't read them back later.
      required:
      - account_number
      - porting_pin
      - account_holder_first_name
      - account_holder_last_name
      - address_line1
      - city
      - state
      - zip
      - country
      properties:
        account_number:
          type: string
          description: Your account number with your current carrier.
          minLength: 1
          maxLength: 64
        porting_pin:
          type: string
          description: Your port-out PIN from your current carrier. If they don't use one, send 0000.
          minLength: 1
          maxLength: 32
          example: '0000'
        account_holder_first_name:
          type: string
          minLength: 1
          maxLength: 80
        account_holder_last_name:
          type: string
          minLength: 1
          maxLength: 80
        address_line1:
          type: string
          minLength: 1
          maxLength: 200
        address_line2:
          type: string
          minLength: 1
          maxLength: 200
        city:
          type: string
          minLength: 1
          maxLength: 120
        state:
          type: string
          minLength: 2
          maxLength: 40
          example: NY
        zip:
          type: string
          minLength: 3
          maxLength: 16
          example: '10001'
        country:
          type: string
          description: Country name.
          minLength: 2
          maxLength: 80
          example: United States
    StartPortRequest:
      type: object
      required:
      - target_e164
      - lnp
      properties:
        target_e164:
          type: string
          description: The number you're bringing to Comms, in E.164 format. It replaces the locked line's number.
          minLength: 8
          maxLength: 20
        lnp:
          $ref: '#/components/schemas/LnpFields'
        authorized:
          type: boolean
          description: Confirm the account holder authorized the transfer. Must be true.
          enum:
          - true
        port_id:
          type: string
          description: 'Recommended: current preparation ID from POST /lock or GET /port. A stale ID is rejected with 409.'
          example: lport_0123456789abcdef
    Error:
      type: object
      properties:
        error:
          type: string
        code:
          type: string
        retry_after:
          type: integer
        reason:
          type: string
    SharedLocation:
      type: object
      required:
      - line_id
      - line_e164
      - from
      - version
      - status
      - checked_at
      - shared_at
      - expires_at
      - location
      properties:
        line_id:
          type: string
        line_e164:
          type: string
        from:
          type: string
          description: The contact sharing their location.
        version:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        status:
          type: string
          enum:
          - sharing
          - stopped
          - expired
          - not_shared
          - unavailable
        checked_at:
          type: string
          format: date-time
        shared_at:
          type:
          - string
          - 'null'
          format: date-time
        expires_at:
          type:
          - string
          - 'null'
          format: date-time
        location:
          type:
          - object
          - 'null'
          required:
          - latitude
          - longitude
          - accuracy_m
          - recorded_at
          properties:
            latitude:
              type: number
              minimum: -90
              maximum: 90
            longitude:
              type: number
              minimum: -180
              maximum: 180
            accuracy_m:
              type:
              - number
              - 'null'
              minimum: 0
            recorded_at:
              type: string
              format: date-time
    NumberChange:
      type: object
      required:
      - id
      - old_e164
      - area_code
      - require_exact_area_code
      - status
      - error_code
      - new_e164
      - created_at
      - updated_at
      - completed_at
      properties:
        id:
          type: string
          pattern: ^gp_[a-f0-9]{32}$
        old_e164:
          type: string
        new_e164:
          type:
          - string
          - 'null'
        area_code:
          type: string
        require_exact_area_code:
          type: boolean
        status:
          type: string
          enum:
          - waiting_for_capacity
          - provisioning
          - verifying
          - completed
          - failed
          - needs_attention
        error_code:
          type:
          - string
          - 'null'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        completed_at:
          type:
          - string
          - 'null'
          format: date-time
    LinePortResponse:
      type: object
      required:
      - port
      properties:
        port:
          $ref: '#/components/schemas/LinePort'
    LinePort:
      type: object
      description: The port's status, times, and errors. The account details you sent are never returned.
      required:
      - id
      - org_id
      - locked_e164
      - status
      - created_at
      - updated_at
      properties:
        id:
          type: string
        org_id:
          type: string
        locked_e164:
          type: string
          description: The dedicated line locked for this port.
        target_e164:
          type:
          - string
          - 'null'
          description: The number you're bringing to Comms. Set once you submit the port.
        status:
          $ref: '#/components/schemas/LinePortStatus'
        error_code:
          type:
          - string
          - 'null'
        error_message:
          type:
          - string
          - 'null'
        submitted_at:
          type:
          - string
          - 'null'
          format: date-time
        foc_at:
          type:
          - string
          - 'null'
          format: date-time
        completed_at:
          type:
          - string
          - 'null'
          format: date-time
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
  responses:
    RateLimited:
      description: Too many requests. Slow down and retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: API key is missing or wrong
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: Your key doesn't have the scope this needs
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: Your API key from the Comms dashboard (`osis_…`).