Skip to content

shipmentComplete

Marks a shipment as COMPLETED. Call this mutation once the parcel has reached its final state — either successfully delivered or returned to sender. Completing a shipment triggers the shipment/completed webhook.

Required scope: edit_shipments


Mutation

graphql
mutation ShipmentComplete($id: String!) {
  shipmentComplete(id: $id) {
    id
    state
  }
}

Arguments

ArgumentTypeRequiredDescription
idStringID of the shipment to complete

Example Variables

json
{
  "id": "ship_550e8400-e29b-41d4-a716-446655440000"
}

Example Response

json
{
  "data": {
    "shipmentComplete": {
      "id": "ship_550e8400-e29b-41d4-a716-446655440000",
      "state": "COMPLETED"
    }
  }
}

Complete Tracking Lifecycle Example

The following Node.js example shows a full shipment lifecycle: create a shipment, push tracking events as they arrive from the carrier, then mark it complete.

js
const API = 'https://api-v3.happycolis.com/graphql';

async function gql(accessToken, query, variables = {}) {
  const response = await fetch(API, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${accessToken}`,
    },
    body: JSON.stringify({ query, variables }),
  });
  const { data, errors } = await response.json();
  if (errors) throw new Error(errors[0].message);
  return data;
}

async function trackingLifecycle(accessToken, deliveryOrderId) {
  // 1. Create the shipment
  const created = await gql(accessToken, `
    mutation ShipmentCreate($input: ShipmentInput!) {
      shipmentCreate(input: $input) {
        shipment { id state }
      }
    }
  `, {
    input: {
      deliveryOrderId,
      carrierName: 'Colissimo',
      tracking: '6C12345678901',
      trackingUrl: 'https://www.laposte.fr/outils/suivre-vos-envois?code=6C12345678901',
    },
  });

  const shipmentId = created.shipmentCreate.shipment.id;
  console.log(`Shipment created: ${shipmentId}`);

  // 2. Carrier received info
  await gql(accessToken, `
    mutation ShipmentAddEvent($input: ShipmentAddEventInput!) {
      shipmentAddEvent(input: $input) { id lastEvent }
    }
  `, {
    input: {
      shipmentId,
      event: 'INFO_RECEIVED',
      date: new Date().toISOString(),
      message: 'Carrier has received shipment information',
    },
  });
  console.log('Event added: INFO_RECEIVED');

  // 3. Parcel in transit
  await gql(accessToken, `
    mutation ShipmentAddEvent($input: ShipmentAddEventInput!) {
      shipmentAddEvent(input: $input) { id lastEvent }
    }
  `, {
    input: {
      shipmentId,
      event: 'IN_TRANSIT',
      date: new Date().toISOString(),
      message: 'Package in transit',
      location: 'Distribution Center Paris',
      city: 'Paris',
      country: 'FR',
    },
  });
  console.log('Event added: IN_TRANSIT');

  // 4. Parcel delivered
  await gql(accessToken, `
    mutation ShipmentAddEvent($input: ShipmentAddEventInput!) {
      shipmentAddEvent(input: $input) { id lastEvent }
    }
  `, {
    input: {
      shipmentId,
      event: 'DELIVERED',
      date: new Date().toISOString(),
      message: 'Package delivered successfully',
      city: 'Lyon',
      country: 'FR',
    },
  });
  console.log('Event added: DELIVERED');

  // 5. Complete the shipment
  const completed = await gql(accessToken, `
    mutation ShipmentComplete($id: String!) {
      shipmentComplete(id: $id) { id state }
    }
  `, { id: shipmentId });

  console.log(`Shipment state: ${completed.shipmentComplete.state}`); // COMPLETED
}

await trackingLifecycle(process.env.ACCESS_TOKEN, 'do_123');

Code Examples

bash
curl -X POST https://api-v3.happycolis.com/graphql \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "query": "mutation ShipmentComplete($id: String!) { shipmentComplete(id: $id) { id state } }",
    "variables": {
      "id": "ship_550e8400-e29b-41d4-a716-446655440000"
    }
  }'
js
async function completeShipment(accessToken, id) {
  const response = await fetch('https://api-v3.happycolis.com/graphql', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${accessToken}`,
    },
    body: JSON.stringify({
      query: `
        mutation ShipmentComplete($id: String!) {
          shipmentComplete(id: $id) {
            id
            state
          }
        }
      `,
      variables: { id },
    }),
  });

  const { data, errors } = await response.json();
  if (errors) throw new Error(errors[0].message);
  return data.shipmentComplete;
}

const result = await completeShipment(
  process.env.ACCESS_TOKEN,
  'ship_550e8400-e29b-41d4-a716-446655440000',
);
console.log(result.state); // "COMPLETED"
python
import os
import requests

def complete_shipment(access_token: str, shipment_id: str) -> dict:
    mutation = """
    mutation ShipmentComplete($id: String!) {
      shipmentComplete(id: $id) {
        id
        state
      }
    }
    """
    response = requests.post(
        'https://api-v3.happycolis.com/graphql',
        headers={
            'Authorization': f'Bearer {access_token}',
            'Content-Type': 'application/json',
        },
        json={'query': mutation, 'variables': {'id': shipment_id}},
    )
    result = response.json()
    if 'errors' in result:
        raise Exception(result['errors'][0]['message'])
    return result['data']['shipmentComplete']

result = complete_shipment(
    os.environ['ACCESS_TOKEN'],
    'ship_550e8400-e29b-41d4-a716-446655440000',
)
print(result['state'])  # "COMPLETED"
php
<?php
$mutation = <<<'GQL'
mutation ShipmentComplete($id: String!) {
  shipmentComplete(id: $id) {
    id
    state
  }
}
GQL;

$payload = json_encode([
    'query'     => $mutation,
    'variables' => ['id' => 'ship_550e8400-e29b-41d4-a716-446655440000'],
]);

$ch = curl_init('https://api-v3.happycolis.com/graphql');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST           => true,
    CURLOPT_POSTFIELDS     => $payload,
    CURLOPT_HTTPHEADER     => [
        'Content-Type: application/json',
        'Authorization: Bearer ' . getenv('ACCESS_TOKEN'),
    ],
]);

$result = json_decode(curl_exec($ch), true);
curl_close($ch);

echo $result['data']['shipmentComplete']['state']; // "COMPLETED"
go
package main

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

func completeShipment(accessToken, id string) (map[string]any, error) {
	mutation := `
		mutation ShipmentComplete($id: String!) {
			shipmentComplete(id: $id) {
				id
				state
			}
		}`

	body, _ := json.Marshal(map[string]any{
		"query":     mutation,
		"variables": map[string]any{"id": id},
	})

	req, _ := http.NewRequest("POST", "https://api-v3.happycolis.com/graphql", bytes.NewBuffer(body))
	req.Header.Set("Content-Type", "application/json")
	req.Header.Set("Authorization", "Bearer "+accessToken)

	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var result map[string]any
	json.NewDecoder(resp.Body).Decode(&result)

	if errs, ok := result["errors"]; ok {
		return nil, fmt.Errorf("graphql error: %v", errs)
	}
	data := result["data"].(map[string]any)
	return data["shipmentComplete"].(map[string]any), nil
}

func main() {
	result, err := completeShipment(
		os.Getenv("ACCESS_TOKEN"),
		"ship_550e8400-e29b-41d4-a716-446655440000",
	)
	if err != nil {
		panic(err)
	}
	fmt.Println(result["state"]) // "COMPLETED"
}

HappyColis API Documentation