Delete all users records using customid/userid

Hello there, I am new to Piwik and Matomo, regarding the new GDPR requirements I need to implement some new function in our website in order to delete all the tracking records done in our website, using the user id.

I went trough the entire documentation and API and I think I am quite lost in here, can someone give me a hand?

I found this method:
UsersManager.DeleteUser (userLogin)

But there isn’t examples, is this what I should look for and test?
What is the userLogin parameter? userId? or something different using some auth hash?

I think there is lack of info in the paremeters and how to use the API =/
Or its just me, that I lack knowledge.

Thank you all,
Apprecited :slight_smile:

This is the API method I need, I really believe:

PrivacyManager.deleteDataSubjects (visits)

The thing is I don’t know how is the syntax of this parameter visits, I pass an array in the URL query? containing the visits ID?


You are right that the documentation is yet missing.

But you can check the GDPR ui tool to see how the API is used:


with the following form-data:

key value
token_auth blablablablablablablabla
visits[0][idsite] 1
visits[0][idvisit] 4759
visits[1][idsite] 6
visits[1][idvisit] 4758
visits[2][idsite] 5
visits[2][idvisit] 4757

You should be able to get idvisit of a single visit from Live.getLastVisitsDetails.

1 Like

Ohhh @Lukas thanks so much for this, I was getting overwhelmed with so many tries.

I am doing an HTTP request to the api, using this method we are discussing.

However I was passing this URL query


And I was always getting an error:
visits array has not idsite key set on visits index 0

I believe there is some markup error in my http URL query, how do I put different object properties of an array index value on the URL query? (noob here sorry eheh)
I am not using form data everything goes in the URL query. I won’t ever use this method for multiple visitIds it will always be single delete of visitId.

Also do you know if there is also a method to get visitId using the userId? From what I was reading the documents, I know visitId is an hash from userId.

Thank you very much for your help!!!
Really appreciated!

Hi guys I finally managed to call the API with the right parameters, I did like you mention @Lukas and it worked calling with success.


And I don’t have error calling the API, but the return of the API show this:

<?xml version="1.0" encoding="utf-8" ?>

It seems like no information from log visit was deleted right?
Then I went into Visit Log inside the Visitors section of the Dashboard, and I still see visit logs (for the day of 1 August) for this specific user with this idvisit I sent in the URL.

So can someone tell me what is wrong? Visit Log is refreshed always from live view (from what I understood… so its not old information I would say).

@Lukas you have any thoughts on this? Thank you very much again :wink:

I know now what was happening!!
I was using Visitor Id instead of VisitId :slight_smile:
I tried with 2 different visit ids of the same user id now and it worked nicely :slight_smile:

I will try now to get all the visits of a specific UserId using the method you showed me called Live.getLastVisitsDetails, thanks @Lukas

1 Like

Hi, I was wondering… if I have hundreds of visitIds to delete… it’s not a good idea to make an HTTP GET Request with such long URL Query string… it seems like according to RFC there isn’t a limit to URL query size… however I read this in stackoverflow:

" RFC 2616 (Hypertext Transfer Protocol — HTTP/1.1) states there is no limit to the length of a query string (section 3.2.1). RFC 3986 also states there is no limit, but indicates the hostname is limited to 255 characters because of DNS limitations (section 2.3.3)."

So what would be a good way to delete hundreds of visitIds in a proper and efficient way?
I thought about using API.getBulkRequest using each visitId to be deleted on a different methods in the URL array, however this would still be a HTTP GET Request with a long URL Query right?

I read that getBulkRequest can be used to make HTTP POST request as well?

“You can also issue the Bulk request as a HTTP POST request to work around any request URI size limitations:”

Anyway… I am trying to use this getBulkRequest but I get an error from the API saying “A task was canceled”, maybe it’s taking too long and the request times out?

To call the API I am using an simple HttpClient from .net framwork calling GetAsync method.

Any help on this? Thanks really want to get the best solution for this, cheers!

It’s working now using the following URL:


But I get for each row of visit this error "Please specify a value for ‘visits’:

error Please specify a value for 'visits'.

I don’t get it :frowning:

PS: I am already doing Url Encode on each query inside the URL array like it says in the documentation


I am not sure as I haven’t tested it, but shouldn’t it be possible to do the exact same query as here:

But just send the parameters via POST.

Hi @Lukas I have been trying for so long, with so many different tries and attempts, but can’t find how to get it to work with bulkRequest, I am using curl and POST the method to test it and I am always returning “Please verify a value for ‘visits’” don’t understand… because the way I use in the normal call http request to PrivacyManager.deleteDataSubjects is the same, check this image:

Here is my query:

c:>curl -i -X POST -d “module=API&method=API.getBulkRequest&idSite=1&period=month&date=2018-08-03&format=xml&token_auth=mytoken&filter_limit=-1&urls[0]=method%3DPrivacyManager.deleteDataSubjects%26visits%5B0%5D%5Bidsite%5D%3D1%26visits%5B0%5D%5Bidvisit%5D%3D34912009&urls[1]=method%3DPrivacyManager.deleteDataSubjects%26visits%5B1%5D%5Bidsite%5D%3D1%26visits%5B1%5D%5Bidvisit%5D%3D34906277&urls[2]=method%3DPrivacyManager.deleteDataSubjects%26visits%5B2%5D%5Bidsite%5D%3D1%26visits%5B2%5D%5Bidvisit%5D%3D34905346” https://blabla/piwik/index.php

As you can see every piece of value in urls[] array is Url Encoded like the documentation advises.

Here is the full query without encoding (line breaks to see each url query separately):

curl -i -X POST -d “module=API&method=API.getBulkRequest&idSite=1&period=month&date=2018-08-03&format=xml&token_auth=6a79a6fd49454b9dc07c70435676ab0d&filter_limit=-1&
method=PrivacyManager.deleteDataSubjects&visits[2][idsite]=1&visits[2][idvisit]=34905346” https://blabla/piwik/index.php

Can you give me some hand here? Thanks again !! :confused:

No one has information on this?
Matomo is open source right? I will try too look into the code itself, thanks anyway :wink:

Any news on this? To comply with data privacy, it is essential for us to be able to delete identified event data upon request of our customers. We expected something like DELETE{uid} ?

Hello! It seems like you are trying to use the Matomo (formerly Piwik) API to delete tracking records based on a user’s ID. The UsersManager.DeleteUser method is not designed for deleting tracking records but rather for deleting a user from the Matomo system.

To delete specific tracking records based on a user ID, you might want to use the TrackingAPI.deleteAllLogs method. However, it’s important to note that the Matomo tracking data is designed to be immutable for privacy reasons. Therefore, directly deleting individual tracking records based on user ID might not align with the usual usage pattern of Matomo.

Here’s a basic example of how you might use TrackingAPI.deleteAllLogs:

const axios = require('axios');

const matomoUrl = 'https://your-matomo-instance-url/matomo.php';
const authToken = 'your-authentication-token';
const userId = 'user-id-to-delete';

async function deleteTrackingRecords() {
  try {
    const response = await, {
      module: 'API',
      method: 'TrackingAPI.deleteAllLogs',
      token_auth: authToken,
      format: 'json',
      user_id: userId,

  } catch (error) {


Replace 'your-matomo-instance-url' with your Matomo instance URL and 'your-authentication-token' with your Matomo authentication token.

Before implementing such changes, make sure you fully understand the implications, and consider consulting with a legal professional to ensure compliance with GDPR requirements. Additionally, always make backups before making changes to tracking data.