Skip to content

variantChangeModel

Required scope: edit_products

Convert a variant's model between PRODUCT and BUNDLE. When converting to BUNDLE, you must provide the component links that define which variants are required and in what quantities. When converting back to PRODUCT, pass an empty links array to clear existing links.


Mutation

graphql
mutation VariantChangeModel(
  $id: String!
  $model: ProductModelEnum!
  $links: [VariantLinkInput!]
) {
  variantChangeModel(id: $id, model: $model, links: $links) {
    id
    model
  }
}

Arguments

ArgumentTypeDescription
idString!The variant UUID to convert
modelProductModelEnum!Target model: PRODUCT or BUNDLE
links[VariantLinkInput!]Component links — required when model is BUNDLE

Input — VariantLinkInput

FieldTypeRequiredDescription
destinationIdStringComponent variant UUID
quantityIntNumber of units required per bundle unit

Example — Convert to BUNDLE

Variables

json
{
  "id": "variant_123",
  "model": "BUNDLE",
  "links": [
    { "destinationId": "variant_tshirt", "quantity": 1 },
    { "destinationId": "variant_mug", "quantity": 1 }
  ]
}

Response

json
{
  "data": {
    "variantChangeModel": {
      "id": "variant_123",
      "model": "BUNDLE"
    }
  }
}

Example — Convert back to PRODUCT

Variables

json
{
  "id": "variant_123",
  "model": "PRODUCT",
  "links": []
}

Code Examples

bash
curl -X POST https://api-v3.happycolis.com/graphql \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "mutation VariantChangeModel($id: String!, $model: ProductModelEnum!, $links: [VariantLinkInput!]) { variantChangeModel(id: $id, model: $model, links: $links) { id model } }",
    "variables": {
      "id": "variant_123",
      "model": "BUNDLE",
      "links": [
        { "destinationId": "variant_tshirt", "quantity": 1 },
        { "destinationId": "variant_mug", "quantity": 1 }
      ]
    }
  }'
js
async function variantChangeModel(accessToken, id, model, links = []) {
  const response = await fetch('https://api-v3.happycolis.com/graphql', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${accessToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: `
        mutation VariantChangeModel(
          $id: String!
          $model: ProductModelEnum!
          $links: [VariantLinkInput!]
        ) {
          variantChangeModel(id: $id, model: $model, links: $links) {
            id
            model
          }
        }
      `,
      variables: { id, model, links },
    }),
  });

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

// Convert to BUNDLE
const variant = await variantChangeModel(accessToken, 'variant_123', 'BUNDLE', [
  { destinationId: 'variant_tshirt', quantity: 1 },
  { destinationId: 'variant_mug', quantity: 1 },
]);

// Convert back to PRODUCT
const product = await variantChangeModel(accessToken, 'variant_123', 'PRODUCT', []);
python
import requests

def variant_change_model(access_token, variant_id, model, links=None):
    response = requests.post(
        'https://api-v3.happycolis.com/graphql',
        headers={
            'Authorization': f'Bearer {access_token}',
            'Content-Type': 'application/json',
        },
        json={
            'query': '''
                mutation VariantChangeModel(
                    $id: String!
                    $model: ProductModelEnum!
                    $links: [VariantLinkInput!]
                ) {
                    variantChangeModel(id: $id, model: $model, links: $links) {
                        id
                        model
                    }
                }
            ''',
            'variables': {
                'id': variant_id,
                'model': model,
                'links': links or [],
            },
        },
    )
    result = response.json()
    if 'errors' in result:
        raise Exception(result['errors'][0]['message'])
    return result['data']['variantChangeModel']

# Convert to BUNDLE
variant = variant_change_model(access_token, 'variant_123', 'BUNDLE', [
    {'destinationId': 'variant_tshirt', 'quantity': 1},
    {'destinationId': 'variant_mug', 'quantity': 1},
])

# Convert back to PRODUCT
variant = variant_change_model(access_token, 'variant_123', 'PRODUCT', [])
php
function variantChangeModel(
    string $accessToken,
    string $variantId,
    string $model,
    array $links = []
): array {
    $client = new \GuzzleHttp\Client();

    $response = $client->post('https://api-v3.happycolis.com/graphql', [
        'headers' => [
            'Authorization' => 'Bearer ' . $accessToken,
            'Content-Type'  => 'application/json',
        ],
        'json' => [
            'query' => '
                mutation VariantChangeModel(
                    $id: String!
                    $model: ProductModelEnum!
                    $links: [VariantLinkInput!]
                ) {
                    variantChangeModel(id: $id, model: $model, links: $links) {
                        id
                        model
                    }
                }
            ',
            'variables' => [
                'id'    => $variantId,
                'model' => $model,
                'links' => $links,
            ],
        ],
    ]);

    $result = json_decode($response->getBody()->getContents(), true);
    if (isset($result['errors'])) {
        throw new \Exception($result['errors'][0]['message']);
    }
    return $result['data']['variantChangeModel'];
}

// Convert to BUNDLE
$variant = variantChangeModel($accessToken, 'variant_123', 'BUNDLE', [
    ['destinationId' => 'variant_tshirt', 'quantity' => 1],
    ['destinationId' => 'variant_mug',    'quantity' => 1],
]);

// Convert back to PRODUCT
$variant = variantChangeModel($accessToken, 'variant_123', 'PRODUCT', []);
go
package main

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

type VariantLinkInput struct {
    DestinationID string `json:"destinationId"`
    Quantity      int    `json:"quantity"`
}

func variantChangeModel(
    accessToken, variantID, model string,
    links []VariantLinkInput,
) (map[string]interface{}, error) {
    query := `
        mutation VariantChangeModel(
            $id: String!
            $model: ProductModelEnum!
            $links: [VariantLinkInput!]
        ) {
            variantChangeModel(id: $id, model: $model, links: $links) {
                id
                model
            }
        }
    `

    body, _ := json.Marshal(map[string]interface{}{
        "query": query,
        "variables": map[string]interface{}{
            "id":    variantID,
            "model": model,
            "links": links,
        },
    })

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

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

    var result map[string]interface{}
    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]interface{})
    return data["variantChangeModel"].(map[string]interface{}), nil
}

// Convert to BUNDLE
variant, err := variantChangeModel(accessToken, "variant_123", "BUNDLE", []VariantLinkInput{
    {DestinationID: "variant_tshirt", Quantity: 1},
    {DestinationID: "variant_mug", Quantity: 1},
})

// Convert back to PRODUCT
variant, err = variantChangeModel(accessToken, "variant_123", "PRODUCT", []VariantLinkInput{})

HappyColis API Documentation