POST /v2/webhooks/register

Webhook登録 (課金対象)

概要

配送追跡用のWebhookを登録します。2つのモードに対応:

  • recurring: true - 配送完了まで継続的にモニタリング (購読型)
  • recurring: false - 1回のみ照会 (単発、デフォルト) 課金対象APIで、最大500件まで一度に登録可能です。

リクエスト例

curl -X POST https://api.whereparcel.com/v2/webhooks/register \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json" \
  -d '{
    "trackingItems": [
      {
        "carrier": "kr.cj",
        "trackingNumber": "123456789012",
        "clientId": "order-001"
      }
    ],
    "recurring": true,
    "webhookEndpointId": "endpoint-id-123"
  }'
const response = await fetch('https://api.whereparcel.com/v2/webhooks/register', {
  method: 'POST',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "trackingItems": [
        {
          "carrier": "kr.cj",
          "trackingNumber": "123456789012",
          "clientId": "order-001"
        }
      ],
      "recurring": true,
      "webhookEndpointId": "endpoint-id-123"
    })
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/register');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$data = [
  'trackingItems' => [
    '0' => [
      'carrier' => "kr.cj",
      'trackingNumber' => "123456789012",
      'clientId' => "order-001"
    ]
  ],
  'recurring' => true,
  'webhookEndpointId' => "endpoint-id-123"
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/register'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

data = {
    'trackingItems': {
        '0': {
            'carrier': "kr.cj",
            'trackingNumber': "123456789012",
            'clientId': "order-001"
        }
    },
    'recurring': True,
    'webhookEndpointId': "endpoint-id-123"
}

response = requests.post(url, headers=headers, json=data)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/register"

	payload := []byte(`{"trackingItems":[{"carrier":"kr.cj","trackingNumber":"123456789012","clientId":"order-001"}],"recurring":true,"webhookEndpointId":"endpoint-id-123"}`)
	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

リクエストボディ

Name Type Required Description
trackingItems array Required
追跡項目 (最大500件)
trackingItems[].carrier string Required
trackingItems[].trackingNumber string Required
trackingItems[].clientId string Optional
recurring boolean Optional
追跡モード (任意、デフォルト: false) - false: 1回のみ照会 (デフォルト、安全) → webhookEndpointId 任意 - true: 継続的にモニタリング (明示的なリクエストが必要) → webhookEndpointId 必須
webhookEndpointId string Optional
事前登録済みのWebhookエンドポイントID - recurring: trueの場合は必須 (ミドルウェアで検証) - recurring: falseの場合は任意 - 指定した場合、完了時にPOST送信。省略した場合は送信なし - 事前にWebhookエンドポイントを登録する必要があります

レスポンス

成功レスポンス (200)

200 OK

Webhook登録成功

Response Body

{
  "success": true,
  "requestId": "req_abc123xyz",
  "subscriptionId": "sub_def456uvw",
  "status": "active",
  "message": "Webhook registered successfully (recurring mode)"
}

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

エラーレスポンス (429)

429 Too Many Requests

リクエスト制限超過

Response Body

{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Please try again later."
  }
}
GET /v2/webhooks/subscriptions

Webhook購読一覧取得

概要

登録したすべてのWebhook購読(購読型+単発)を取得します。無料APIで使用量は消費されません。

リクエスト例

curl -X GET https://api.whereparcel.com/v2/webhooks/subscriptions \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json"
const response = await fetch('https://api.whereparcel.com/v2/webhooks/subscriptions', {
  method: 'GET',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  }
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/subscriptions');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/subscriptions'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/subscriptions"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

レスポンス

成功レスポンス (200)

200 OK

購読一覧の取得に成功しました

Response Body

[
  {
    "requestId": "req_abc123xyz",
    "trackingItemCount": 2,
    "trackingItems": [
      {
        "carrier": "kr.cj",
        "trackingNumber": "300718039335",
        "clientId": "order-001",
        "latestStatus": "delivered"
      },
      {
        "carrier": "kr.lotte",
        "trackingNumber": "410259694563",
        "latestStatus": "in_transit"
      }
    ],
    "recurring": true,
    "webhookEndpointId": "endpoint_xyz789",
    "isActive": true,
    "createdAt": "2026-02-05T10:00:00.000Z",
    "updatedAt": "2026-02-05T14:30:00.000Z"
  },
  {
    "requestId": "req_def456uvw",
    "trackingItemCount": 1,
    "trackingItems": [
      {
        "carrier": "kr.post",
        "trackingNumber": "1234567890123",
        "latestStatus": "out_for_delivery"
      }
    ],
    "recurring": false,
    "isActive": false,
    "progress": {
      "total": 1,
      "completed": 1,
      "succeeded": 1,
      "failed": 0,
      "percentage": 100
    },
    "createdAt": "2026-02-04T09:00:00.000Z",
    "updatedAt": "2026-02-04T09:05:00.000Z",
    "completedAt": "2026-02-04T09:05:00.000Z"
  }
]

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}
GET /v2/webhooks/subscriptions/{requestId}

単一Webhook購読取得

概要

特定のrequestIdのWebhook購読情報を取得します。無料APIで使用量は消費されません。

リクエスト例

curl -X GET https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId} \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json"
const response = await fetch('https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}', {
  method: 'GET',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  }
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

パスパラメータ

Name Type Required Description
requestId string Required
<p>Webhook登録時に受け取ったrequestId</p>
Example: req_abc123xyz

レスポンス

成功レスポンス (200)

200 OK

購読情報の取得に成功しました

Response Body

{
  "success": true,
  "data": {
    "requestId": "req_abc123xyz",
    "trackingItemCount": 1,
    "trackingItems": [
      {
        "carrier": "kr.cj",
        "trackingNumber": "123456789012",
        "latestStatus": "in_transit"
      }
    ],
    "recurring": true,
    "webhookEndpointId": "endpoint-id-123",
    "isActive": true,
    "createdAt": "2026-02-05T10:00:00.000Z",
    "updatedAt": "2026-02-05T10:00:00.000Z"
  }
}

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

エラーレスポンス (404)

404 Not Found

requestIdが見つかりません

Response Body

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource was not found"
  }
}
DELETE /v2/webhooks/subscriptions/{requestId}

Webhook購読削除

概要

Webhook購読をキャンセルし、モニタリングを停止します。購読型(recurring)Webhookの場合は即座に停止されます。無料APIで使用量は消費されません。

リクエスト例

curl -X DELETE https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId} \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json"
const response = await fetch('https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}', {
  method: 'DELETE',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  }
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

response = requests.delete(url, headers=headers)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}"

	req, _ := http.NewRequest("DELETE", url, nil)

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

パスパラメータ

Name Type Required Description
requestId string Required
<p>削除するWebhookのrequestId</p>
Example: req_abc123xyz

レスポンス

成功レスポンス (200)

200 OK

購読の削除に成功しました

Response Body

{
  "deleted": true,
  "requestId": "req_abc123xyz",
  "message": "Webhook subscription deleted successfully"
}

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

エラーレスポンス (404)

404 Not Found

requestIdが見つかりません

Response Body

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource was not found"
  }
}
GET /v2/webhooks/subscriptions/{requestId}/changes

Webhook変更履歴取得

概要

特定のWebhook購読のすべての変更履歴(配送ステータス変更)を取得します。無料APIで使用量は消費されません。

リクエスト例

curl -X GET https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json"
const response = await fetch('https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes', {
  method: 'GET',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  }
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

パスパラメータ

Name Type Required Description
requestId string Required
<p>Webhook登録時に受け取ったrequestId</p>
Example: req_abc123xyz

レスポンス

成功レスポンス (200)

200 OK

変更履歴の取得に成功しました

Response Body

{
  "events": [
    {
      "eventId": "evt_abc123",
      "requestId": "req_abc123xyz",
      "webhookUrl": "https://myapp.com/webhooks/whereparcel",
      "event": "status.changed",
      "payload": {
        "trackingNumber": "300718039335",
        "carrier": {
          "code": "kr.cj",
          "name": "CJ대한통운"
        },
        "previousStatus": "in_transit",
        "currentStatus": "out_for_delivery",
        "trackingData": {
          "carrier": "kr.cj",
          "carrierName": "CJ대한통운",
          "trackingNumber": "300718039335",
          "status": "out_for_delivery",
          "statusText": "배달 출발",
          "events": [
            {
              "timestamp": "2026-02-05T09:15:00+09:00",
              "status": "out_for_delivery",
              "statusText": "배달 출발",
              "location": "서울 강남구 센터"
            }
          ]
        },
        "timestamp": "2026-02-05T09:15:00+09:00"
      },
      "status": "delivered",
      "deliveryAttempts": 1,
      "createdAt": "2026-02-05T09:15:00.000Z",
      "updatedAt": "2026-02-05T09:16:00.000Z"
    },
    {
      "eventId": "evt_def456",
      "requestId": "req_abc123xyz",
      "webhookUrl": "https://myapp.com/webhooks/whereparcel",
      "event": "status.delivered",
      "payload": {
        "trackingNumber": "300718039335",
        "carrier": {
          "code": "kr.cj",
          "name": "CJ대한통운"
        },
        "previousStatus": "out_for_delivery",
        "currentStatus": "delivered",
        "trackingData": {
          "carrier": "kr.cj",
          "carrierName": "CJ대한통운",
          "trackingNumber": "300718039335",
          "status": "delivered",
          "statusText": "배달완료",
          "events": [
            {
              "timestamp": "2026-02-05T14:30:00+09:00",
              "status": "delivered",
              "statusText": "배달완료",
              "location": "서울 강남구"
            }
          ]
        },
        "timestamp": "2026-02-05T14:30:00+09:00"
      },
      "status": "delivered",
      "deliveryAttempts": 1,
      "createdAt": "2026-02-05T14:30:00.000Z",
      "updatedAt": "2026-02-05T14:31:00.000Z"
    }
  ],
  "pagination": {
    "limit": 20,
    "nextCursor": "cursor_xyz789",
    "hasMore": false
  }
}

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

エラーレスポンス (404)

404 Not Found

requestIdが見つかりません

Response Body

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource was not found"
  }
}
GET /v2/webhooks/subscriptions/{requestId}/changes/{changeId}

単一変更イベント取得

概要

特定の変更イベントの詳細情報を取得します。無料APIで使用量は消費されません。

リクエスト例

curl -X GET https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes/{changeId} \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json"
const response = await fetch('https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes/{changeId}', {
  method: 'GET',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  }
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes/{changeId}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes/{changeId}'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/subscriptions/{requestId}/changes/{changeId}"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

パスパラメータ

Name Type Required Description
requestId string Required
<p>Webhook登録時に受け取ったrequestId</p>
Example: req_abc123xyz
changeId string Required
<p>変更イベントID</p>
Example: change_def456

レスポンス

成功レスポンス (200)

200 OK

変更イベントの取得に成功しました

Response Body

{
  "eventId": "evt_abc123",
  "requestId": "req_abc123xyz",
  "webhookUrl": "https://myapp.com/webhooks/whereparcel",
  "event": "status.changed",
  "payload": {
    "trackingNumber": "300718039335",
    "carrier": {
      "code": "kr.cj",
      "name": "CJ대한통운"
    },
    "previousStatus": "in_transit",
    "currentStatus": "out_for_delivery",
    "trackingData": {
      "carrier": "kr.cj",
      "carrierName": "CJ대한통운",
      "trackingNumber": "300718039335",
      "status": "out_for_delivery",
      "statusText": "배달 출발",
      "events": [
        {
          "timestamp": "2026-02-05T09:15:00+09:00",
          "status": "out_for_delivery",
          "statusText": "배달 출발",
          "location": "서울 강남구 센터"
        },
        {
          "timestamp": "2026-02-05T08:00:00+09:00",
          "status": "in_transit",
          "statusText": "배송 중",
          "location": "서울 송파구 센터"
        }
      ]
    },
    "timestamp": "2026-02-05T09:15:00+09:00"
  },
  "status": "delivered",
  "deliveryAttempts": 1,
  "maxAttempts": 3,
  "createdAt": "2026-02-05T09:15:00.000Z",
  "updatedAt": "2026-02-05T09:16:00.000Z"
}

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

エラーレスポンス (404)

404 Not Found

requestIdまたはchangeIdが見つかりません

Response Body

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "The requested resource was not found"
  }
}
POST /v2/webhooks/results

Webhook結果バッチ検索

概要

複数の荷物のWebhook結果を一度に検索します。 登録したWebhookの最終結果を照会する際に使用します。

検索方式:

  • carrier + trackingNumberで検索
  • clientIdで検索
  • 両方の方式を同時に使用可能

動作方式:

  • tracking_requestsコレクションのtrackingIndex/clientIdIndexフィールドを使用して検索
  • 同じ追跡番号が複数のドキュメントにある場合、最新のドキュメントのみ返却
  • Firestore array-contains-any制限(10件)によるバッチ処理 (最大100件照会時に10回クエリ)

無料APIで使用量は消費されません。

リクエスト例

curl -X POST https://api.whereparcel.com/v2/webhooks/results \
  -H "Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production" \
  -H "Content-Type: application/json" \
  -d '{
    "trackingItems": [
      {
        "carrier": "kr.cj",
        "trackingNumber": "300718039335"
      },
      {
        "carrier": "kr.lotte",
        "trackingNumber": "410259694563"
      }
    ]
  }'
const response = await fetch('https://api.whereparcel.com/v2/webhooks/results', {
  method: 'POST',
  headers: {
    "Authorization": "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
      "trackingItems": [
        {
          "carrier": "kr.cj",
          "trackingNumber": "300718039335"
        },
        {
          "carrier": "kr.lotte",
          "trackingNumber": "410259694563"
        }
      ]
    })
});

const data = await response.json();
console.log(data);
<?php

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://api.whereparcel.com/v2/webhooks/results');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');

$headers = [
  'Authorization: Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
  'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$data = [
  'trackingItems' => [
    '0' => [
      'carrier' => "kr.cj",
      'trackingNumber' => "300718039335"
    ],
    '1' => [
      'carrier' => "kr.lotte",
      'trackingNumber' => "410259694563"
    ]
  ]
];
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));

$response = curl_exec($ch);
curl_close($ch);

$result = json_decode($response, true);
print_r($result);
import requests
import json

url = 'https://api.whereparcel.com/v2/webhooks/results'

headers = {
    'Authorization': 'Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production',
    'Content-Type': 'application/json'
}

data = {
    'trackingItems': {
        '0': {
            'carrier': "kr.cj",
            'trackingNumber': "300718039335"
        },
        '1': {
            'carrier': "kr.lotte",
            'trackingNumber': "410259694563"
        }
    }
}

response = requests.post(url, headers=headers, json=data)

result = response.json()
print(result)
package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

func main() {
	url := "https://api.whereparcel.com/v2/webhooks/results"

	payload := []byte(`{"trackingItems":[{"carrier":"kr.cj","trackingNumber":"300718039335"},{"carrier":"kr.lotte","trackingNumber":"410259694563"}]}`)
	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(payload))

	req.Header.Add("Authorization", "Bearer wp_test_public_demo_key_do_not_use_in_production:sk_test_public_demo_secret_do_not_use_in_production")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)
	defer res.Body.Close()

	body, _ := io.ReadAll(res.Body)
	fmt.Println(string(body))
}
💡 注記: テスト用APIキーをダッシュボードで発行した実際のAPIキーに置き換えてください。

リクエストボディ

Name Type Required Description
trackingItems array Required

レスポンス

成功レスポンス (200)

200 OK

バッチ検索成功

Response Body

{
  "results": {
    "kr.cj:300718039335": {
      "source": "webhook",
      "data": {
        "carrier": "kr.cj",
        "carrierName": "CJ대한통운",
        "trackingNumber": "300718039335",
        "status": "delivered",
        "statusText": "배달완료",
        "events": [
          {
            "timestamp": "2026-02-05T14:30:00+09:00",
            "status": "delivered",
            "statusText": "배달완료",
            "location": "서울 강남구"
          },
          {
            "timestamp": "2026-02-05T09:15:00+09:00",
            "status": "out_for_delivery",
            "statusText": "배달 출발",
            "location": "서울 강남구 센터"
          }
        ]
      },
      "requestId": "sub_abc123xyz",
      "createdAt": "2026-02-05T10:00:00.000Z"
    },
    "clientId:order-002": {
      "source": "webhook",
      "data": {
        "carrier": "kr.lotte",
        "carrierName": "롯데택배",
        "trackingNumber": "410259694563",
        "status": "in_transit",
        "statusText": "배송 중",
        "events": [
          {
            "timestamp": "2026-02-05T12:00:00+09:00",
            "status": "in_transit",
            "statusText": "배송 중",
            "location": "경기 성남시"
          }
        ]
      },
      "requestId": "sub_def456uvw",
      "createdAt": "2026-02-05T10:00:00.000Z"
    }
  }
}

エラーレスポンス (401)

401 Unauthorized

認証失敗

Response Body

{
  "success": false,
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key"
  }
}