> ## Documentation Index
> Fetch the complete documentation index at: https://developer.voyado.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Challenges

A challenge defines a path towards a goal and motivates the customer to reach it. The path consists of a number of checkpoints and awards can either be given when the end goal has been reached and the challenge is completed, or at certain checkpoints along on the way. Challenges allows the retailer to drive engagement, rewarding desired actions and behaviors and making customers feel more involved.

## Use cases for challenges

The more basic concept of a stamp card is included in challenges, but challenges can be used for so much more. The use cases are basically endless. A customer can also have more than one challenge running at the same time, increasing engagement. Here’s a few examples of what you can do with Engage challenges:

* Ask customers to submit five product reviews, each review counting as one checkpoint
* Help customers gear up for their hike, setting checkpoints for different outdoor products
* Encourage customers to shop in your physical store, then make a purchase online, then "like" your Instagram page, and finally subscribe to your newsletter, each action being a checkpoint.
* Activate a sustainability-themed challenge focused on refreshing, repairing, and recycling products, or reward customers for bringing their own bag for in-store purchases.

The following section will detail the API endpoints used in Challenges. For more help and guides, you can visit [this page ](https://help.engage.voyado.com/hc/en-gb/articles/17234962807580-Challenges-in-Engage)in Engage's Help Center.

## IDs used in challenges

Three different IDs are used when working with the challenges API:

* **Contact ID**: The usual Engage contact ID, used to uniquely identify a contact.
* **Definition ID**: The *definition* of a challenge, its basic structure or template, has a unique definition ID. A challenge definition will have the same definition ID from when it's created to when it's destroyed.
* **Challenge ID**: Assigning a challenge definition to a contact creates a specific "instance" of that definition, which then belongs to that contact alone. This instance is called a challenge, and is given a unique challenge ID. Each challenge ID is therefore *uniquely connected to one contact ID and definition ID*.

## The challenges API endpoints

The challenges API consists of 6 endpoints.

```http Get all challenges assigned to a contact theme={null}
GET /api/v3/challenges
```

```http Get specific challenge assigned to a contact theme={null}
GET /api/v3/challenges/{challengeId}
```

```http Get all challenge definitions theme={null}
GET /api/v3/challenges/definitions
```

```http Get specific challenge definition theme={null}
GET /api/v3/challenges/definitions/{definitionId}
```

```http Award checkpoints in challenge (can be batched) theme={null}
POST /api/v3/challenges/checkpoints
```

```http Assign and activate challenge for contact theme={null}
POST /api/v3/challenges/definitions/{definitionId}/assign
```

These endpoints will now be considered in more detail.

## Get all challenges for contact

This endpoint returns all of a contact's challenges, even the completed ones.

```http theme={null}
GET /api/v3/challenges
```

<Tip>
  All of these parameters are sent in the query string.
</Tip>

<ResponseField name="contactId" type="int" required>
  The contact's unique ID
</ResponseField>

<ResponseField name="definitionId" type="int">
  Restrict the results to only that challenge definition
</ResponseField>

<ResponseField name="offset" type="int">
  Can be used to paginate the results
</ResponseField>

<ResponseField name="count" type="int">
  Can be used to paginate the results
</ResponseField>

<ResponseField name="filter" type="string">
  Narrow the results to "All", "Active", "Completed" or "NotCompleted"
</ResponseField>

## Get specific challenge for contact

Use this endpoint to get the full details of an assigned challenge, including the contact's progress, using the challenge ID. A challenge is only ever connected to *one* contact, so the contact ID is not required in the request.

```http theme={null}
GET /api/v3/challenges/{challengeId}
```

The response will look something like this:

```json theme={null}
{
  "challengeId": "081225de-8a42-45f8-a3b7-03d9c97ee19c",
  "challengeStart": "2023-09-21T10:52:38.2535557+02:00",
  "completedCheckpoints": 2,
  "contactId": "2285d25b-622c-45ce-bc13-fccdd1147d4d",
  "id": "3a4a81c3-ea2c-4f4c-866b-6dcadf257759",
  "isActive": false,
  "isChallengeCompleted": false,
  "latestCheckpointAddedOn": "2023-09-26T10:52:38.2535557+02:00",
  "requiredCheckpoints": 5,
  "status": 3,
  "links": [
    {
      "id": "3a4a81c3-ea2c-4f4c-866b-6dcadf257759",
      "href": "https://yoururl/api/v3/challenges/3a4a81c3-ea2c-4f4c-866b-6dcadf257759",
      "method": "GET",
      "rel": "self"
    },
    {
      "id": "081225de-8a42-45f8-a3b7-03d9c97ee19c",
      "href": "https://yoururl/api/v3/challenges/definitions/081225de-8a42-45f8-a3b7-03d9c97ee19c",
      "method": "GET",
      "rel": "definition"
    }
  ]
}
```

## Get all challenge definitions

This endpoint returns a list of all challenge definitions in your Engage environment.

```http theme={null}
GET /api/v3/challenges/definitions
```

<Tip>
  All of these parameters are sent in the query string.
</Tip>

<ResponseField name="offset" type="int">
  Can be used to paginate the results
</ResponseField>

<ResponseField name="count" type="int">
  Can be used to paginate the results
</ResponseField>

<ResponseField name="status" type="string">
  "All" (the default) as well as "Active", "Draft", "Scheduled" or "Ended"
</ResponseField>

A successful request will return something like this:

```json theme={null}
{
  "links": [
    {
      "href": "",
      "method": "GET",
      "rel": "previous"
    },
    {
      "href": "",
      "method": "GET",
      "rel": "next"
    }
  ],
  "count": 1,
  "offset": 0,
  "items": [
    {
      "checkpointAssignOn": 2,
      "checkpointAssignOnAmount": 1,
      "createdBy": "Joe Doe",
      "createdOn": "2023-07-08T09:21:39.9997785+02:00",
      "description": "Buy 5 get one for free",
      "expirationMonths": 5,
      "id": "74bb66f1-6993-442e-bb93-e41e1ecc3184",
      "isContactConsentRequired": false,
      "isScheduled": false,
      "modifiedBy": "Jane Doe",
      "modifiedOn": "2023-07-18T09:21:39.9997785+02:00",
      "name": "Dog food",
      "requiredNumberOfCheckpoints": 5,
      "status": 1,
      "links": []
    }
  ],
  "totalCount": 1
}
```

## Get specific challenge definition

This returns a specific challenge definition based on its unique definition ID.

```http theme={null}
GET /api/v3/challenges/definitions/{definitionId}
```

The response is essentially a single object from the "items" array of the previous endpoint.

## Award checkpoints for contact

Use this endpoint to progress a contact along a specific challenge. The `definitionId` of the challenge and the `contactId` must be sent in the payload, along with the number of checkpoints to be added.

<Tip>
  Updates to several contacts can be batched in the same request.
</Tip>

```http theme={null}
POST /api/v3/challenges/checkpoints
```

The payload is sent in the body of the query as follows:

```json theme={null}
[
  {
    "definitionId": "bbf8d0a3-7057-4b21-9fd1-a9ba21116d5c",
    "contactId": "96465573-53e7-453f-a2d9-fa65a68de111",
    "checkpointAmount": 1
  }, 
  {
    "definitionId": "bbf8d0a3-7057-4b21-9fd1-a9ba21116d5c",
    "contactId": "63706fea-10d9-459e-a78a-1011486fb46f",
    "checkpointAmount": 2
  },
  {
    "definitionId": "2b84e222-2f84-4553-a775-7755ea912e52",
    "contactId": "be541846-34e2-4bb2-b693-b4c5a31c27b9",
    "checkpointAmount": 1
  }
]
```

<Warning>
  Incorrect data will still result in an accepted response code, but that block in the payload will be skipped. Engage will continue to process the next block.
</Warning>

In the case of incorrect data, the *HTTP 200 OK* response will contain details of the error like this:

```json theme={null}
{
  "missingContactIds": [
    "a311f9f9-9bdc-4b85-9f6c-b269ab204038"
  ],
  "missingDefinitionIds": [
    "4524db0c-4d43-417e-b437-d75ca2cda3a6"
  ],
  "notAccepted": [
    {
      "definitionId": "4524db0c-4d43-417e-b437-d75ca2cda3a6",
      "contactId": "aace6d91-3f0f-472e-9583-b9e5c4acbaa1",
      "checkpointAmount": 2
    },
    {
      "definitionId": "0c469396-d94d-4f86-934d-244d6080c353",
      "contactId": "a311f9f9-9bdc-4b85-9f6c-b269ab204038",
      "checkpointAmount": 1
    }
  ]
}
```

## Assign challenge to contact

This creates an assignment of a specific challenge for a specific contact and activates it with an initial checkpoint count of zero.

```http theme={null}
POST /api/v3/challenges/definitions/{definitionId}/assign
```

<ResponseField name="contactId" type="int" required>
  The contact's unique ID sent in the query string
</ResponseField>

<ResponseField name="definitionId" type="int" required>
  The challenge's defiition ID sent in the request path
</ResponseField>

A *HTTP 200 OK* response with the value of "true" will be returned if the assignment was successfully created (or if it already exists).

<Tip>
  A challenge is configured so that the contact always has to give their approval to be assigned the challenge. This approval is handled by the retailer and it's up to their internal process to decide when a challenge can and should be activated for a contact *before* this endpoint is called. Calling the endpoint will always activate the challenge.
</Tip>
