Agent Skill · Sinch

sinch-porting-api

Port phone numbers from other carriers into Sinch with the Porting API. Automates port-in order creation, portability checks, order tracking, on-demand activation, and webhook notifications. Use when porting numbers, checking portability, creating port-in orders, tracking port status, activating ported numbers, uploading LOA documents, or configuring porting defaults.

Provider: Sinch Path in repo: skills/sinch-porting-api/SKILL.md

Skill body

Sinch Porting API

Overview

The Porting API automates port-in operations — transferring phone numbers from another carrier into Sinch. It supports portability checks, order creation and management, document uploads, on-demand activation, and webhook notifications for status updates. Currently supports North American (US/CA) numbers only.

Agent Instructions

Before generating code, gather from the user (skip any item already specified in the prompt or context):

  1. Use case — portability check, create order, track order, or activate numbers?
  2. Activation mode (only for create order) — Automatic (on desiredPortDate) or on-demand (onDemandActivation: true)?
  3. Language — any language, or curl. The @sinch/sdk-core Node.js SDK does not currently have dedicated porting methods — use direct HTTP for all porting operations.

Refer to the API reference linked in Links for request/response schemas.

Security: See the Security section below for url fetching policy, handling inbound webhook content, and credential handling.

Getting Started

Agent Credentials handling

Store credentials in environment variables — never hardcode tokens, PINs, or keys in commands or source code:

export SINCH_PROJECT_ID="your-project-id"
export SINCH_KEY_ID="your-key-id"
export SINCH_KEY_SECRET="your-key-secret"
export SINCH_ACCESS_TOKEN="your-oauth-token"

Authentication

Ensure that authentication headers are properly set when making API calls. The Porting API uses Bearer token authentication:

-H "Authorization: Bearer $SINCH_ACCESS_TOKEN"

See sinch-authentication for full setup, most importantly how to obtain {SINCH_ACCESS_TOKEN} (OAuth2 client-credentials — do not mint your own JWT).

Base URL

Environment URL
Production https://porting.api.sinch.com/v1/projects/{PROJECT_ID}

First API Call — Check Portability

Always check portability before creating an order:

curl -X POST \
  "https://porting.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/portabilityChecks" \
  -H "Authorization: Bearer $SINCH_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phoneNumbers": ["+15551234567", "+15559876543"]
  }'

Response:

{
  "phoneNumbers": [
    {
      "phoneNumber": "+15551234567",
      "portable": true,
      "carrier": "T-Mobile"
    },
    {
      "phoneNumber": "+15559876543",
      "portable": false,
      "carrier": "Verizon",
      "reason": "Number is not portable"
    }
  ]
}

Create a Port-In Order

curl -X POST \
  "https://porting.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/orders/portIns" \
  -H "Authorization: Bearer $SINCH_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "desiredPortSchedule": {
      "desiredPortDate": "2026-05-15",
      "desiredPortTime": "09:00:00",
      "desiredPortTimeZone": "US/Eastern"
    },
    "customerOrderReference": "my-ref-123",
    "phoneNumbers": [
      {
        "phoneNumber": "+15551234567",
        "endUser": {
          "name": "Acme Corp",
          "streetNum": "123",
          "streetName": "Main",
          "streetType": "St",
          "city": "Anytown",
          "state": "CA",
          "zipCode": "90210",
          "typeOfService": "B"
        },
        "portOutInfo": {
          "existingPortOutPin": "1234"
        }
      }
    ]
  }'

existingPortOutPin — Obtain this PIN from the losing carrier before submitting the order. See Create Port-In Order for full field reference.

Response:

{
  "id": 12345,
  "status": "PENDING",
  "customerOrderReference": "my-ref-123",
  "desiredPortSchedule": {
    "desiredPortDate": "2026-05-15",
    "desiredPortTime": "09:00:00",
    "desiredPortTimeZone": "US/Eastern"
  },
  "phoneNumbers": [
    {
      "phoneNumber": "+15551234567",
      "status": "PENDING"
    }
  ]
}

Track an Order

# Auth: same Bearer token header as above
curl -X GET \
  "https://porting.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/orders/portIns/12345" \
  -H "Authorization: Bearer $SINCH_ACCESS_TOKEN"

Response:

{
  "id": 12345,
  "status": "CONFIRMED",
  "customerOrderReference": "my-ref-123",
  "desiredPortSchedule": {
    "desiredPortDate": "2026-05-15",
    "desiredPortTime": "09:00:00",
    "desiredPortTimeZone": "US/Eastern"
  },
  "phoneNumbers": [
    {
      "phoneNumber": "+15551234567",
      "status": "CONFIRMED",
      "focDate": "2026-05-15"
    }
  ]
}

Activate Numbers (On-Demand)

First check which number groups are ready:

# Auth: same Bearer token header as above
curl -X GET \
  "https://porting.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/orders/portIns/12345/availableActivations" \
  -H "Authorization: Bearer $SINCH_ACCESS_TOKEN"

Response:

{
  "activationGroups": [
    {
      "groupId": "grp-001",
      "phoneNumbers": ["+15551234567"],
      "status": "READY"
    }
  ]
}

Then activate:

# Auth: same Bearer token header as above
curl -X POST \
  "https://porting.api.sinch.com/v1/projects/$SINCH_PROJECT_ID/orders/portIns/12345/activate" \
  -H "Authorization: Bearer $SINCH_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "groupIds": ["grp-001"]
  }'

Key Concepts

Common Patterns

Gotchas and Best Practices

Security

Skill frontmatter

metadata: {"author" => "Sinch", "version" => "1.0.4", "category" => "Numbers", "tags" => "porting, port-in, number-transfer, carrier, portability, loa, foc, activation", "uses" => ["sinch-authentication"]}