---
# System prepended metadata

title: What's new in v0.25

---

# What's new in v0.25

Take a look at some of the most significant changes in MeiliSearch v0.25

## Intro

This month’s release brings many improvements to API key management and asynchronous operations. In this article, we will take a look at some of the main and breaking changes. You can also read the [full changelog on GitHub](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.25.0).

## Breaking changes

### API key management

Starting from this release, developers can now create API keys with specific permissions and expiration dates, allowing precise control over which users/applications can access which indexes and endpoints.

As part of this feature, the `private` and `public` keys are deprecated and replaced by two default API keys with similar permissions: `Default Admin API Key` and `Default Search API Key`.

Let's say that you're creating an application in the medical industry. Here's how to create an API key that only has access to search endpoints on the `patient_medical_records` index:

```bash
curl \
    -X POST 'http://localhost:7700/keys/' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer [your_master_key]' \
    --data-binary '{
      "description": "Search patient records key",
      "actions": [
        "search"
      ],
      "indexes": ["patient_medical_records"],
      "expiresAt": "2023-01-01T00:00:00Z"
    }'
```

**Response: `201 Created`**

```json
{
    "description": "Search patient records key",
    "key": "d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4",
    "actions": [
        "search"
    ],
    "indexes": [
        "patient_medical_records"
    ],
    "expiresAt": "2023-01-01T00:00:00Z",
    "createdAt": "2022-01-01T10:00:00Z",
    "updatedAt": "2022-01-01T10:00:00Z"
}
```

A user could then supply this key to make search requests on the `patient_medical_records` index:

```bash
curl \
    -X POST 'http://localhost:7700/indexes/patient_medical_records/search' \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer d0552b41536279a0ad88bd595327b96f01176a60c2243e906c52ac02375f9bc4' \
    --data-binary '{ "q": "trypophobia" }'
```


Note that the `X-MEILI-API-KEY: <apiKey>` header has been replaced by the `Authorization: Bearer <apiKey>` header.

For more information, read our new guide to [securing a MeiliSearch instance](https://docs.meilisearch.com/reference/features/security.html).


### Asynchronous operations

With v0.25, we refashioned MeiliSearch's asynchronous operations from the ground up, replacing the `updates` API with the new `tasks` API.

In a related change, creating, updating, and deleting indexes are now asynchronous operations. This fix eliminates the potential for race conditions.

#### Tracking tasks

Before v0.25, any request handled asynchronously (e.g. adding documents) returned an `updateId` for tracking the status of the operation:

```json
{ "updateId": 1 }
```

After v0.25, asynchronous operations will now return a summarized version of the *task* object:

```json
{
    "uid": 1,
    "indexUid": "patient_medical_records",
    "status": "enqueued",
    "type": "documentAddition",
    "enqueuedAt": "2021-08-10T14:29:17.000000Z",
}
```

You can get the full *task* object—and the current status of the operation—using the `/tasks` route.

```bash
curl \
    -X GET 'http://localhost:7700/indexes/patient_medical_records/tasks/1'
```

**Response: `200 Ok`**


```json
{
    "uid": 1,
    "indexUid": "patient_medical_records",
    "status": "succeeded",
    "type": "documentAddition",
    "details": { 
            "receivedDocuments": 1,
            "indexedDocuments": 1
    },
    "duration": "PT1S",
    "enqueuedAt": "2021-08-10T14:29:17.000000Z",
    "startedAt": "2021-08-10T14:29:18.000000Z",
    "finishedAt": "2021-08-10T14:29:19.000000Z"
}
```
Here the task has succeeded. Other possible statuses for a task are `enqueued`, `processing`, or `failed`.

When a task fails, MeiliSearch returns an `error` object as part of the response:

```json
{
    "uid": 2,
    "indexUid": "patient_medical_records",
    "status": "failed",
    "type": "documentAddition",
    "details": { 
            "receivedDocuments": 1,
            "indexedDocuments": 0
    },
    "error": {
        "message": "Document does not have a `:primaryKey` attribute: `:documentRepresentation`.",
        "code": "internal",
        "type": "missing_document_id",
        "link": "https://docs.meilisearch.com/errors#missing-document-id",
    },
    "duration": "PT1S",
    "enqueuedAt": "2021-08-11T14:29:17.000000Z",
    "startedAt": "2021-08-11T14:29:18.000000Z",
    "finishedAt": "2021-08-11T14:29:19.000000Z"
}
```

For more information, check out the [Asynchronous operations](https://docs.meilisearch.com/learn/advanced/asynchronous_operations.html) article or the [tasks API reference](https://docs.meilisearch.com/reference/api/tasks.html).


## Other changes    
- **Cross-version compatibility:** MeiliSearch v0.25 and subsequent releases are incompatible with dumps created prior to v0.22.
To migrate a dump from pre-v0.22 to v0.25 MeiliSearch, first load your dump into v0.24.0, create a dump using v0.24.0, and then import this dump into v0.25.0.
- We have added several new error messages, most of which are related to managing API keys.
- `matches` now highlights string and numeric values.
- We added some new telemetry metrics.

    
## Contributors

A big thank you to all our contributors! This project couldn't get very far without your help.

Thanks to [@Mcdostone](https://github.com/Mcdostone) and [@Thearas](https://github.com/Thearas) for your help with MeiliSearch, and to [@datamaker](https://github.com/datamaker) and [@Samyak2](https://github.com/Samyak2) for your help with our Tokenizer library.


---

If you want more details on updates we didn’t mention here, check out our [release changelog](https://github.com/meilisearch/MeiliSearch/releases/tag/v0.25.0).