---
title: Sending Data to Custom Entities via the Admin API | Shopware Community Hub
description: >-
  Learn how to use the Shopware Admin API to authenticate, locate Custom Entity
  endpoints, send data records and configure permissions in the manifest.xml
  file.
canonical_url: 'https://hub.shopware.com/learn/unit/app-uploading-custom-entity-data'
---

# Sending Data to Custom Entities via the Admin API

<LearningObjectives>

- **Authenticate** against the Shopware Admin API by generating an **OAuth token**.
- Send a **POST request** to **create and send data records** for a Custom Entity.
- Understand how **API permissions** in the **manifest.xml** file **control access** to Custom Entities.
- Practice using tools like **Postman or cURL** to **interact** with the Shopware **Admin API**.

</LearningObjectives>

# Sending Data to Custom Entities via the Admin API

In this learning unit, we will learn how to interact with the **Shopware Admin API** to send data to our Custom Entity.

This learning unit is a **manual deep dive** into the API authentication process. In real-world scenarios, your **App Server** will handle this automatically, as you will see in the next course.

Still, understanding how it works under the hood helps you better grasp authentication and permissions.

<Callout title="Spotlight API reference" type="info">

For full details about Shopware's API and best practices when making requests, check the [Spotlight Admin API docs](https://shopware.stoplight.io/docs/admin-api/twpxvnspkg3yu-quick-start-guide).

</Callout>

<Callout title="Assuming the Role of the App Server" type="warning">

In this guide, we will manually send data via an API client. This is **only recommended for learning purposes**. In real projects, the App Server should always send Custom Entity data programmatically.

</Callout>

## Code-Along

To follow along, use this command within the ShopwareStoreTracker directory:

```bash
git checkout tags/api_upload--start
```

## Leveraging Your Local API Reference

By default, every Custom Entity exposes its own API endpoint for typical **Create**, **Read**, **Update** and **Delete** (CRUD) operations.

To identify these endpoints, Shopware provides a local API reference (powered by [Stoplight](https://stoplight.io/)).
While running Shopware in dev mode, open `http://localhost:8000/api/_info/stoplightio.html/` into your browser. You should see a page like this:

![local API reference home](assets/localhost-spotlight-home.png)

If our App is successfully installed and activated, you will find `Ce Physical Shop` in the side menu:

![Local Spotlight Ce Physical Shop](assets/localhost-spotlight-physicalShop.png)

### Selecting an API Client

To interact with the endpoints, you need a tool to send API requests. You can use:

- A command-line tool, such as [`curl`](https://curl.se/) on Linux.
- A GUI-based API client such as [Postman](https://www.postman.com/) or [Insomnia](https://insomnia.rest/).

In this learning unit, we will use **Postman** for simplicity. If you are unfamiliar with it, check the [Postman Docs](https://learning.postman.com/docs/introduction/overview/).

<Callout title="Pre-defined Postman Collection" type="info">

To save time, you can import our [**Postman collection**](assets/App-Development.postman_collection.json).

</Callout>

### Creating a New API Integration in Shopware

Before making API calls, we need to [create an API integration](https://docs.shopware.com/en/shopware-6-en/settings/system/integrationen#create-integration). This will give us the `client_credentials` to authenticate and to use the Shopware Admin dashboard.

1. Open [`http://localhost:8000/admin`](http://localhost:8000/admin) in your browser. Go to **Settings** and click on **Integrations** in the **System** section.

    ![Integrations menu icon](assets/shopware6_7-administration-settings-integration.png)

2. Click the **Add integration** button in the top-right corner to create a new integration for your App.

    ![Integrations page](assets/administration-integrations.png)

3. In the integration modal, select the role `ShopwareStoreTracker` from the list.

    ![Selecting a role](assets/administration-integration-role.png)

4. Generate a new API secret by clicking the red button.

    ![Client secret](assets/administration-integration-createNewAPIKey.png)

<Callout title="Store API Secret Safely" type="warning">

Write the API secret down somewhere safely (e.g., a text file). Once you close the modal, you cannot see the secret again. If you only copy it to your clipboard, it may get overwritten and lost.

</Callout>

<Callout title="Real Apps Don't Require Manual Integrations" type="info">

In this learning example, you created an integration manually to better understand how **OAuth authentication** works.

However, when a Shopware App is installed, Shopware **automatically creates and manages an integration** for that App, including credentials and permissions.

This means that in production scenarios, an administrator **does not need to create a separate integration** manually. The App communicates with the Shopware Admin API automatically through its internal integration.

</Callout>

## API Authentication

The first step to interact with the Shopware Admin API is to [authenticate](https://shopware.stoplight.io/docs/admin-api/authentication) using the API credentials you created earlier(`client_id`, `client_secret`).

### OAuth API Request

The request is provided via curl here. It can be [imported into Postman](https://learning.postman.com/docs/getting-started/importing-and-exporting/importing-curl-commands/) quite simply:

```bash
curl --location 'http://[hostname]/api/oauth/token' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
  "grant_type": "client_credentials",
  "client_id": "[clientId]",
  "client_secret": "[clientsecret]"
}'
```

<Callout title="Note on the Hostname" type="info">

From here on, the placeholder **`http://[hostname]`** refers to your Shopware instance. If you are running Shopware locally, it will be **`http://localhost:8000`**.

</Callout>

#### Importing the Request Into Postman (Optional)

1. Copy the request above and import it to Postman.
  ![postman_import_button](assets/postman-importButton.png)
  ![postman_import_modal_blank](assets/postman-import-modal-blank.png)
  ![postman_curl_request_added](assets/postman-import-modal-curlContent.png)

2. Adapt the values in the request to match your local environment.
  ![postman_curl_request_imported](assets/postman-curl-content_imported.png)
  ![postman_request_values_adapted](assets/postman-request-parameter-filled.png)
  The base URL is the one you defined in your local machine, in this example it is `localhost:8000`. The body is `x-www-form-urlencoded` and the body-parameters are `grant_type`, `client_id` and `client_secret`. The value from `grand_type` is `client_credentials`, the other two are the values of the integration we generated before.

3. Get the OAuth token by pressing the **Send** button.
  ![postman_bearer_token_generated](assets/postman-bearerToken-generated.png)

<Callout title="Tip" type="info">

If you get lost with Postman, try the same request with `cURL` in your terminal, both work the same way.

</Callout>

We're now successfully authenticated, take the token via copy-paste, and let's start constructing requests!

## Adding Physical Shop Records to the Database

Let's construct a new Postman request to send the provided data to the Shopware Server – we will send our data via `POST` to our generated endpoint:

### Entity Create Request

To add data into the `ce_physical_shop` entity, we will use the following request:

```bash
curl --location 'http://[hostname]/api/ce-physical-shop' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer [authToken]' \
--data-raw '{
    "name": "Mumbai Design Ltd",
    "streetAddress": {
        "street": "101 Sangbhai",
        "townOrCity": null,
        "countyOrProvince": null,
        "zipCode": "1A7071"
    },
    "country": "India",
    "description": null,
    "email": "info@mumbaidesign.com",
    "phone": "+1.906.758.3469"
}'
```

Copy the request above and import it to Postman as shown in the previous section. Add the bearer token/OAuth token under `Authorization`. Select the type as `Bearer Token`, add your token and press send.

With the relevant substitutions, our request is ready to send. If we do press send now, though, we will get an error!

```json
{
    "errors": [
        {
            "status": "403",
            "code": "FRAMEWORK__MISSING_PRIVILEGE_ERROR",
            "title": "Forbidden",
            "detail": "{\"message\":\"Missing privilege\",\"missingPrivileges\":[\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\",\"ce_physical_shop:create\"]}",
            "meta": {
                "parameters": []
            },
            "trace": [
				...
            ]
        }
    ]
}
```

This error is the result of a missing configuration in our App's `manifest.xml` file. The `ShopwareStoreTracker` role we selected for our API integration is currently not allowed to perform operations on any entities, including any physical shops. Let's fix that.

### Assigning Permissions to `ShopwareStoreTracker`

As you learned in the second learning unit, your App's permissions are defined in the `permissions` section of the `manifest.xml` file. Now, extend this section by adding the `ce_physical_shop` entity so your App can create, read, update, and delete records for it.

```xml
    <permissions>
        <read>ce_physical_shop</read>
        <create>ce_physical_shop</create>
        <update>ce_physical_shop</update>
        <delete>ce_physical_shop</delete>
    </permissions>
```

After saving the manifest file, update your App, retry the **POST** request above. You should now receive a list of UUIDs, indicating that the record creation was successful.

```json
{
    "extensions": [],
    "data": {
        "ce_physical_shop": [
            "01948fcee0f77286aaeaa89d13c15e37",
            "01948fcee0f97000b9ab7b1bca9bedb0",
            "01948fcee0f97000b9ab7b1bcad9bb19",
            "01948fcee0f97000b9ab7b1bcb563cd1",
            "01948fcee0f97000b9ab7b1bcbac510a",
            "01948fcee0f97000b9ab7b1bcc8ac700",
            "01948fcee0f97000b9ab7b1bccde02fb",
            "01948fcee0f97000b9ab7b1bcce6ff12",
            "01948fcee0f97000b9ab7b1bcd751b9b"
        ],
        "ce_physical_shop_translation": [
            {
                "cePhysicalShopId": "01948fcee0f77286aaeaa89d13c15e37",
                "languageId": "2fbb5fe2e29a4d70aa5854ce7ce3e20b"
            },
        ...
        ]
    }
}
```

## Code-Along (end)

At this point, your App should be able to send data records to the `ce_physical_shop` entity. If you want to compare your progress with the final version, run the following command in your App directory:

```bash
git checkout tags/api_upload--end
```

<Callout title="Removing Working Changes" type="warning">

If you have local modifications, run `git reset --hard HEAD` in the App directory. Be aware that this command will delete any local changes!

</Callout>

## Admin API vs. Store API

Before we close this learning unit, it is important to clarify how the **Admin API** differs from the **Store API**, as they serve distinct purposes in the Shopware ecosystem.

The **Admin API permissions**, configured in the `manifest.xml`, define which entities your App may create, read, update, or delete via the Admin API. They do **not** control access to storefront data.

The **Store API** exposes only fields explicitly marked as `store-api-aware` and the visibility depends on the request context (e.g., sales channel). Admin API permissions **do not automatically** make data available through the Store API.

## Summary

In this learning unit, you learned how to make an API request to the Shopware administration and create demo records for a Custom Entity.

Key takeaways:

- You can use the **Shopware Admin API** to create, read, update and delete records for your Custom Entities.
- Authentication is done with an **OAuth token**, which you generate via an API integration.
- Permissions for your App must be defined in the **manifest.xml** file. Without them, the API will reject your requests.

In real projects, the App Server will handle data exchange automatically (e.g., via [webhooks](https://developer.shopware.com/docs/guides/plugins/apps/webhook.html)). But practicing the manual API requests gives you a solid understanding of how the system works under the hood.

Congratulations! You have completed the **Custom Entities** course. This knowledge is a cornerstone for more advanced milestones. Now you are ready to move forward with confidence!
