Making API Requests 
Overview 
In this guide you'll learn how to create a custom API service in your plugin's administration to make HTTP requests to the Shopware API. This is useful when you need to communicate with custom backend endpoints or extend Shopware's API functionality.
Prerequisites 
In order to add your own custom API service for your plugin, you first need a plugin as base. Therefore, you can refer to the Plugin Base Guide.
You also need to have a custom administration module or component. Refer to Add custom module to get started.
Creating the API service 
First, create a new API service class that extends Shopware's ApiService class. This provides you with all the necessary methods for authentication and HTTP communication.
Create the service file in your plugin's administration source directory:
// <plugin root>/src/Resources/app/administration/src/api/my-api-service.js
const { ApiService } = Shopware.Classes;
class MyApiService extends ApiService {
    constructor(httpClient, loginService, apiEndpoint = '_action/my-plugin') {
        super(httpClient, loginService, apiEndpoint);
    }
    // GET request example
    getMyData() {
        const apiRoute = `${this.getApiBasePath()}/my-data`;
        return this.httpClient
            .get(apiRoute, {
                headers: this.getBasicHeaders(),
            })
            .then((response) => {
                return ApiService.handleResponse(response);
            });
    }
    // POST request example with data
    createMyData(data) {
        const apiRoute = `${this.getApiBasePath()}/my-data`;
        return this.httpClient
            .post(
                apiRoute,
                data,
                {
                    headers: this.getBasicHeaders(),
                }
            )
            .then((response) => {
                return ApiService.handleResponse(response);
            });
    }
    // DELETE request example
    deleteMyData(id) {
        const apiRoute = `${this.getApiBasePath()}/my-data/${id}`;
        return this.httpClient
            .delete(apiRoute, {
                headers: this.getBasicHeaders(),
            })
            .then((response) => {
                return ApiService.handleResponse(response);
            });
    }
    // GET request with query parameters
    searchMyData(searchTerm, limit = 25) {
        const apiRoute = `${this.getApiBasePath()}/my-data/search`;
        return this.httpClient
            .get(apiRoute, {
                params: {
                    term: searchTerm,
                    limit: limit,
                },
                headers: this.getBasicHeaders(),
            })
            .then((response) => {
                return ApiService.handleResponse(response);
            });
    }
}
export default MyApiService;Registering the service 
To make your API service available throughout your plugin's administration, you need to register it as a service provider. Create an index file to handle the registration:
// <plugin root>/src/Resources/app/administration/src/api/index.js
import MyApiService from './my-api-service';
const { Application } = Shopware;
Application.addServiceProvider('myApiService', (container) => {
    const initContainer = Application.getContainer('init');
    return new MyApiService(
        initContainer.httpClient,
        container.loginService
    );
});Don't forget to import this file in your plugin's main administration entry point:
// <plugin root>/src/Resources/app/administration/src/main.js
import './api';
// ... other importsUsing the API service in components 
Now you can inject and use your API service in any component within your plugin:
// <plugin root>/src/Resources/app/administration/src/module/my-module/component/my-component/index.js
import template from './template.twig';
const { Component, Mixin } = Shopware;
Component.register('my-component', {
    template,
    inject: ['myApiService'],
    mixins: [Mixin.getByName('notification')],
    data() {
        return {
            myData: [],
            isLoading: false,
        };
    },
    created() {
        this.loadData();
    },
    methods: {
        async loadData() {
            this.isLoading = true;
            
            try {
                this.myData = await this.myApiService.getMyData();
                
                this.createNotificationSuccess({
                    message: 'Data loaded successfully',
                });
            } catch (error) {
                this.createNotificationError({
                    message: error.message || 'An error occurred',
                });
            } finally {
                this.isLoading = false;
            }
        },
        async saveData(data) {
            this.isLoading = true;
            
            try {
                await this.myApiService.createMyData(data);
                
                this.createNotificationSuccess({
                    message: 'Data saved successfully',
                });
                
                // Reload data after saving
                await this.loadData();
            } catch (error) {
                this.createNotificationError({
                    message: error.message || 'Failed to save data',
                });
            } finally {
                this.isLoading = false;
            }
        },
        async deleteItem(id) {
            try {
                await this.myApiService.deleteMyData(id);
                
                this.createNotificationSuccess({
                    message: 'Item deleted successfully',
                });
                
                // Reload data after deletion
                await this.loadData();
            } catch (error) {
                this.createNotificationError({
                    message: error.message || 'Failed to delete item',
                });
            }
        }
    },
});Working with authentication 
The ApiService base class automatically handles authentication by including the necessary headers. The getBasicHeaders() method provides:
- Authorization token
 - Content-Type headers
 - API version headers
 
If you need custom headers, you can extend them:
getCustomData() {
    const headers = {
        ...this.getBasicHeaders(),
        'X-Custom-Header': 'custom-value'
    };
    return this.httpClient
        .get(`${this.getApiBasePath()}/custom-endpoint`, { headers })
        .then((response) => {
            return ApiService.handleResponse(response);
        });
}Error handling 
The ApiService.handleResponse() method automatically handles common HTTP errors. However, you should still implement proper error handling in your components:
async performApiCall() {
    try {
        const result = await this.myApiService.getMyData();
        // Handle success
    } catch (error) {
        // Check for specific error types
        if (error.response) {
            // The request was made and the server responded with a status code
            // that falls out of the range of 2xx
            console.error('Error status:', error.response.status);
            console.error('Error data:', error.response.data);
        } else if (error.request) {
            // The request was made but no response was received
            console.error('No response received:', error.request);
        } else {
            // Something happened in setting up the request
            console.error('Error:', error.message);
        }
    }
}Advanced usage 
File uploads 
For file uploads, you can use FormData:
uploadFile(file) {
    const formData = new FormData();
    formData.append('file', file);
    
    return this.httpClient.post(
        `${this.getApiBasePath()}/upload`,
        formData,
        {
            headers: {
                ...this.getBasicHeaders(),
                'Content-Type': 'multipart/form-data',
            },
        }
    ).then((response) => {
        return ApiService.handleResponse(response);
    });
}Accessing standard Shopware APIs 
You can also access Shopware's standard APIs using the repository pattern:
Component.register('my-component', {
    inject: ['repositoryFactory'],
    computed: {
        productRepository() {
            return this.repositoryFactory.create('product');
        }
    },
    methods: {
        async loadProducts() {
            const criteria = new Shopware.Data.Criteria();
            criteria.setPage(1);
            criteria.setLimit(25);
            
            const products = await this.productRepository.search(criteria);
            // Use products...
        }
    }
});Next steps 
Now that you've created your API service, you might want to:
- Create the corresponding backend API endpoints
 - Add more complex API interactions
 - Implement caching strategies for better performance
 - Add request interceptors for global error handling
 
For more information on creating backend API endpoints, refer to the API documentation.