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
| Argument | Type | Description |
|---|---|---|
id | String! | The variant UUID to convert |
model | ProductModelEnum! | Target model: PRODUCT or BUNDLE |
links | [VariantLinkInput!] | Component links — required when model is BUNDLE |
Input — VariantLinkInput
| Field | Type | Required | Description |
|---|---|---|---|
destinationId | String | ✅ | Component variant UUID |
quantity | Int | ✅ | Number 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{})