 Hi everyone, welcome back. I will be talking a little bit about the DHS2 API today and a little bit about the data model of DHS2, which can be quite complex. So it may be review for some people, but I feel like it doesn't hurt to have a review on the data model, especially when you're thinking about it from the perspective of an application developer, which might be different than from the perspective of someone who's implementing DHS2 or using DHS2 as well. Let me go ahead and get into this presentation here. So when we talk about DHS2, there's a lot of different pieces to that. This is a description of kind of the model of what DHS2 is. And we have the core, which has the API, the data model and the server of DHS2. And then we have bundled applications that come out of the box with the DHS2 war file. Beyond that, we have periphery applications, which are applications that are built on the application platform or the Android SDK, but aren't developed by the core team of UIO. And beyond that, we have interoperability with other systems. So this is just a very high level overview of what the DHS2 ecosystem looks like, but today we're gonna be focusing just on the middle piece. So at least for this session, we'll be talking about the core and particularly the API, the REST API that is exposed by DHS2 and how you can use that in your web applications and Android applications as well. So there are two different major sort of sections of the API or the data model in DHS2 and those are metadata and data. There's some other things as well that we won't get into as much today. Those are things like analytics, file resources, stuff like that that don't fit exactly into metadata or data. But for now, we're gonna talk about what is metadata, what is data and how do you operate on those things through the REST API? Metadata is, as I've sort of described here, tried to describe it in plain English, but it's the configuration of a particular DHS2 system to determine how data is collected and how it's analyzed. So for instance, DHS2 has a concept of org units but there are no org units built into DHS2 that has to be defined by the server or the implementation that is using DHS2 software. So the configuration of which org units are defined, which data elements are defined, which indicators are defined in a particular system, we refer to that as metadata. And there's a lot of that, we'll get into a little bit of it but that could be a whole separate course on how to configure the metadata of a DHS2 instance. Today we'll just talk about how to interact with the API to view and edit that information. We also have data, which is the actual values that are collected in through the DHS2 system. So in traditional aggregate health management information systems, you collect, for instance, a number every month. So you might collect the number 42 every month or it might be a different number each month but every month somebody at a clinic is entering the number 42. That 42 is the data, but without the metadata, you don't know what that 42 means. So that could be a number of births, could be the number of deaths, it could be the number of doses of a vaccine given, could be any number of things. So data is just the value and then it's associated with metadata to figure out what that actually means. And so it associated with the metadata to figure out the what, the where and the when of this particular collection of information. I'm going to go to the next slide. Actually, I'm going to skip to this one first. So just to explain a little bit what I just said, so you have a data value might be the number 42. That is associated with a data element, a period and an org unit. And therefore we know that that number 42 might be the number of deaths in February 2020 for the, I don't know, the region of the, I'm in France. So the region of the France, the main province of France. So that with those four things together, the number as well as what, where and when that number was collected for, you have information enough to do some analysis on that. But the data value by itself, which is just the number 42, doesn't necessarily have that information. There are a lot of other types of metadata as well. So we had metadata, we had data element, we had org unit, we also had a period, which isn't on this list. But there's a lot of other pieces of metadata to configure DHS to and customize it in a lot of different ways. These are, this is a set of some of them. It's not all of them, but this lets you kind of see the complexity of the data that could be modeled in DHS to. Each one of these has an API endpoint that lets you list out all of the indicator group sets or all of the organization units or all of the category option combos for a particular DHS to instance using the REST API. And we'll get into how to do that in a couple of minutes. This is again, all of this is metadata. So this is not data. There are no actual values in these, the responses from these API endpoints. So there's a different way to interact with the API when you're talking about metadata versus when you're talking about data. And we'll talk a little bit about that in a few minutes. There, most people are probably familiar with this, but there's a concept of org units and a hierarchy of org units in DHS to. And that is again configured for each instance of DHS to. You have typically the national level is the top level of your organization unit hierarchy. And then below that, you might have a district, then you might have a chiefdom or a county or a province and then you might have a facility level. So at this, typically in most health management information systems, you have all the way from the national level through maybe a district or a chiefdom to a facility. And that facility is often a hospital or a clinic or maybe a vaccine distribution site or those types of things. And that is a hierarchy. So facilities belong to a chiefdom, which belongs to a district, which belongs to a particular nation. These also have associated geographic areas or geometries. So the nation of Sierra Leone has borders and those borders are modeled in DHS too as well. Similarly, each district within Sierra Leone has a different border. And then a facility, which is the lowest level here, is located at a specific point on a map. And so you can also use the API to interact with the locations of these things in an interesting way. We won't get into too much of that today. Jose will talk a little bit more about some of the tracker specific things that we work with here, I think, but I wanted to also point out the difference between tracker and aggregate. So we have aggregate, which is, as I mentioned, it might be the number of doses given in a particular month or a particular quarter at a particular place, or it might be the number of deaths from malaria or something like that. That is more about routine data sets and it doesn't have any identifying information about who those deaths were or who those vaccines were given to. It's only collecting a number or kind of an aggregate value. Tracker is about capturing what's known as longitudinal information about individuals. It's not necessarily about always referring to people. It might also be a batch of vaccines, could also be a tracked entity instance. But the concept of tracker is to identify events that happen to a particular thing, whether that's a person or a batch of vaccines or something like that, over time. It could also be a building. There's lots of different ways to model information in DHS too. But this is identifiable and associated with that particular thing. In most cases, that's a person, so a patient, for instance, and then tracking the things that happen to that person over time. So that might be for a pre and postnatal care program that might be checkups that are given to a pregnant woman before she gives birth. And then maybe there's a new tracked entity instance for the baby that's born and then vaccination events that happen to that baby. They're administered to that baby and then that is tracked in DHS2 tracker so that you can see that this particular person received these treatments or exhibited these symptoms of a disease or those types of things. Again, it's completely open-ended. So different DHS2 instances can model this in different ways. And that's very important to keep in mind, especially when you're building applications that are intended to be generic and used across different DHS2 instances is that you can't necessarily assume that everyone has modeled their metadata in the same way. So now we'll talk a little bit about the web API. The core of DHS2 is a huge Java application with lots going on inside of it and it exposes a REST API. If you're not familiar with REST API, you can Google it, it's a fairly common term, but it basically means that you are sending an HTTP request to a particular URL and getting a response back and it should be, yeah, basically it's one form of designing that API. I won't get into too much of the specifics of what REST API means. To access the API, obviously you need a session. So in a browser, you can log in to the URL of your DHS2 instance, you log in with your credentials, it sets a cookie in your browser and then you can just browse the API using get requests from your browser, just like normal. So we'll get into how to do that in a minute. If you're not using a browser, you can use an authorization header. This is not recommended for production use cases because it can be quite expensive for the server. It can also potentially expose your username and password if you're not careful about protecting it, but for testing, this is a nice way to experiment with the API. So you have to basically encode the string with a particular, like basically to base 64 from text. You can Google basic authentication, type in your username and password, though I wouldn't recommend doing that. And you should be able to, it should tell you how to create a base 64 encoded string and then you put that in a header in your DHS2 instance. If you're using something like Postman, it will do this for you. You just put your username and password into Postman and it will do the encoding for you already. We'll talk about Postman as a tool in a minute. To navigate through the API, there are a few different ways to kind of do that. One of the main ones I would say is actually just going to the documentation. So docs.dhs2.org, I'll show that in a minute, but you can also do some navigation through the API itself. So if you go to slash API slash resources, it will list all of the metadata endpoints that are available in that system. The metadata endpoints might change slightly between different versions of DHS2, though they're fairly consistent for some time. If you go to slash resources, it will list all of the different metadata resources that are available. There's something like 85 of them. So there's quite a few. Some are used much more than others. So don't worry, don't be overwhelmed by how many there are. It'll also tell you the singular and plural version of that name when it appears in the API. So when you have references to this resource, for instance, Program to Tract Entity Attribute Group, that will be referred to as, when it's singular, it will be referred to as a Program Tract Entity Attribute Group. And when it's plural, it's a collection of multiple Program Tract Entity Attribute Groups. And then this is the most important one. You have an HREF link here, which will show you where to get the list of all of the Program Tract Entity Attribute Groups in a particular instance. This is a little bit of an older slide, so I don't know that this actually is the right metadata endpoint to demonstrate, but we can show that looking for slash API slash resources, it will list out all of the ones that are available in that particular instance. You can then, as I mentioned, go to slash API slash the name of that resource, and that will last, list all of the metadata items of a certain type. There are some parameters that are available in that, I'll get into that in a minute. Here are those parameters. So when you're looking at metadata endpoints, so this, a very simple one to think about is indicators. So indicators are, they're basically just a calculation that DHIS2 does to determine some number from a combination of other numbers. So it might be the number of, let's see, the number of vaccinations for a particular vaccine that are usually given to people that are children that are under five years old, divided by, or under one year old, divided by the number of births that year. So that gives you kind of what percentage based on the number of people that you know were born and the number of people that were given this vaccine under, that is supposed to be given when they're under one year old, you know what your coverage is for that value. So that's one example of metadata and we'll get into too much of how to model things, but you can get a list of all the indicators in an instance if you go to slash API slash a version number slash indicators. I'm gonna go quickly over to a browser here to show this. Let's to go to our Academy instance. You can still see my screen, is that correct? Yeah, I think you can. Yes, yes, we can. Cool. Okay, so we're gonna go, this is our instance. I just logged in. So now the browser knows has the cookies for my session. So I can start to navigate the API. We're gonna go to that API slash resources endpoint. By default, this shows XML. You can also do question mark format equals JSON and it will give you the same thing in JSON, which is nice. Pretty much all of the endpoints accept this format parameter. You can also do dot JSON on some endpoints as well. So this is the list of all of the metadata endpoints that are available in this DHS-2 instance. Let's go and find that indicators that I just talked about. Here we have, oops. So there's also program indicators, which is tracker instead of aggregate, but we're not gonna deal with that today. So we have this indicators link here, which goes to slash API slash indicators. It's also important when you're actually navigating through the API, it's fine to use slash API because that is typically redirected to the most recent version. But I know that this version is on 235, I believe, maybe 236, and so I can use the 35 API version and that will fix the responses to the version that a 35 server knows about. And so I can do the same thing with 35 in that endpoint as well. It's important to note that if you're using the SDK in Android or if you're using the app runtime on the web, you don't need to make these API requests directly. They do it for you. And you also don't need to specify the API version, for instance, because that's automatically determined for you in most cases. So here we have the list of indicators. You'll see that we have two things going on here. We have paging, so we have something called a pager here. I'm gonna turn this into a JSON, so it's a little bit easier to read. So we have pager, which has, we're currently on the first page. There are two pages total. The total number of indicators in this system are 83 and our page size is 50, which means that we'll return 50 items per page. So here we have the first 50 indicators in this system. So now if we go back to our list of parameters here, we have paging, which defaults to true. You can use paging equals false, but do not do that, please. So this has been something that has caused a lot of problems for us in very large instances, particularly with COVID-19, as we're starting to get situations where you have thousands or millions of items that might be returned if you have paging equals false. So in this case, it returned 83 items, but if this had 10,000 indicators or 10,000 org units, which is very common, or not very common, but does happen in a number of DHS2 instances, this is really problematic. So you can do paging false, but don't do it. It might be removed in the future, and we actually warn you not to do it in the app runtime as well. But you can change the size of this paging. So we have, as I mentioned, we have this pager and we also have indicators as the two fields here in this response. In pager, we're on the first page, our page count is two and our page size is 50, but 50 is a lot to display at one time. So maybe we only want to display 10, let's say page size equals 10. So I can pass this as a parameter to the REST API. This is called a query string parameter. And when I do that, now our page size is 10, you'll see that there are only 10 indicators listed here. And we still have the total size, total number of indicators is 83, but now our total page count has gone up because we're only showing 10 per page. This is page one, so this is indicators one through 10. We then have 11 through 20, and then 21 through 30, et cetera, until we get to 83. So there are nine total pages. If we wanted to see what that next page would be, we can add the page parameter here as well. So and page equals two. So now our page is two, we're getting the, this is numbers 11 through 20, and page equals three is numbers 21 through 30. So you can actually go through the list of all of the different indicators, counting 10 at a time and get them back. And the reason that you always want to use paging for metadata endpoints particularly, is that if there's a huge number, number one, it will take a very long time to download all of that information, which probably you won't actually be able to display to the user in a meaningful way. And number two, it could even crash the browser, in some cases, if there are so many indicators that need to be downloaded, it might take many megabytes of memory and then the browser becomes unusable and your user gets very frustrated. And in some cases, it might be very bad even for the server, because if you have 10 million tracked entity instances and you're trying to download all of them, which luckily the API won't allow you to do, but if you had a million of something and the server needed to load that into memory before giving it to the browser and you had 10 different people using your application that becomes very, very expensive very quickly. So always use paging, you can specify page size and page to indicate how you want to do this pagination. There's, yeah, so here we talked about page size, we talked about page. Now let's talk a little bit about fields and filter. So you'll see here that the default fields, I'm gonna get rid of this. I'm just gonna do page size one. So now with page size one, we actually only get one response back. You can actually specify, so yeah, I'll do this here. I'm gonna do page size three just so we can see all of them on the same page. You'll see that each of these has an ID and a display name. So for indicators, the default fields is ID and display name, but I would recommend that you always specify exactly which fields you want. So if you only care about ID and you don't need display name, you can just say ID and then you only get the ID back from this endpoint. So this is the ID of all of those indicators that you're talking about. Probably display name is an interesting thing to look at. So let's keep that in there. Maybe we also want the code. So DHS2, I'm not gonna get into how to identify objects in DHS2, but there are three different ways. You can use the ID, the code, actually ID and code are the main ones. And we can get into more details about that later, but there's also often a code that is manually specified for a particular indicator. Name, I guess is the other one. Name is the third one. Another important thing to note here is that display name, which is listed here, is you can also use name, but I would not recommend it. So display name will be translated. Name will not be translated. So if you have translations for metadata in your DHS2 instance, and you use the name field, it will always be in whatever the default language is. Whereas if you have display name, and let's say you have both English and French names, and this user is a French user, they will see those names in French rather than in English. And users that are English speakers will see those names in English instead. And similarly for every other language that you have to find in your system. And so here we have ID, display name and code. We can also do star. So this gives me all of the fields that are available for this particular indicator. I'm gonna go to the next slide because I had to talk a little bit more about that here. Nope, this one. So we talked about having a single field name. So you have a... Actually, I have one more here. So you have the name, for instance, or you might have ID, code and display name. You can have also complex ones, which I'll get into in a minute. And then you can also have these, which are called presets. So star is a preset, colon some name is a preset. There are a few other options there. So star is the same as colon all. And this basically gives you all of the available values, and there are quite a few for this particular instance. I would also recommend, as this slide says, do not use these presets. We actually warn you in DHS2 app runtime not to use the star or all presets because it could download way more information than you need and you're not really clear what you want to download. So if you specify, you can use this... Sorry, this is here. You can use this to see what data is available when you're just exploring the API, but when you actually want to do it, or want to use it in your application, you should always specify exactly which fields you want. So we have, let's say we have ID, display name, and then remember this was an indicator, which has a numerator and denominator, and it divides the numerator by the denominator to get some indicator value, which is the percentage of how good you're doing or what is going on in this system. So let's get the numerator and the denominator here as well. All right, so then we're back down to a reasonable amount of information. Remember, even if you're paging and you use the star or the all, you get a lot more than you bargained for. So we have these translations here, for instance, that we don't need all of those for every time we download because if we're using display name, then we have the full name or we have the translated name already. We also don't need, for instance, let's say there's indicator groups. So if there were a ton of indicator groups associated with this indicator, this would be a very, very long list that unless we're actually working with indicator groups, it doesn't make a lot of sense to do that. But we can, so if we go back to our one here where we have ID, display name, numerator and denominator, we have also indicator groups. So if we do indicator groups, we'll see that list come back. This is a little bit dangerous because it can be problematic when these lists are very large. So you can also do paging, which is by default paged to 50, but we'll get into that separately. So indicator groups, and then you can specify if you use either a parentheses or a bracket, you can specify what you want within this indicator group. So let's get the ID, the display name, and the code for each of these indicator groups. And it looks like these indicator groups don't actually have a code, but you have the ID and display name, which I've specified here. As a warning in the future, they're using a code, which doesn't exist on indicator groups, will become an error. The server will throw an error in the future. So try not to use fields that don't exist if they don't. So if you did my field or something that doesn't exist, right now it just comes back with nothing, but in the future that might throw an error. So this is how right here, I'm sorry, this is a little small. I'll go back to the slide. This and this are ways to drill down and expand the response. So we're talking about an indicator and we could also see the ID of the indicator group that's associated with that indicator and go make another request to indicator groups slash that ID, but instead we're going to just specify that we want the name and the ID or whatever else from that indicator group or in this case, user within that response. There are also some operators for doing things like renaming or paging collections within the DHS2 API. You can find more about that at docs.dh2.org. I'm not going to go into too much today. You can also look at schemas. So this is another way to explore. This is defining kind of the hierarchy of metadata in a DHS2 system, but I won't get into that too much either. For filters, so we talked about paging, page size, page, fields, filter also works here for collections. So if you have a collection, you can use a bunch of different, you can use a bunch of different filters to specify exactly what you want to return. So let's go back to our list of indicators here. I'm going to get rid of most of these and just get the default again. So now we have A and C, one to three, one and two. Let's add a filter which says and filter equals display name. Now let's go back here and look at some of these operators that are available. There are quite a few, but I'm going to use dollar like, which is a dollar I like, I guess, which is a case in sensitive string testing, a particular thing. Actually, let's do an equals first. So let's say display name equals this one. So this will return just one. Hopefully if we do this right. So now we return, we basically are filtering this list. So this is still the all indicators endpoint. We're filtering it down to only the one that has this exact display name. Now let's change that to display name dollar I like A and C. So this will be, oops, yeah, there we go, dollar I like A and C. So this gives you all of the indicators that are starting with the word A and C. This is really helpful for things like searching. So we have, again, we're paging and we only are allowing three per page. There's a total of 11 that start with A and C. So let's make 20 our page size so we can see them all. These are all of the 11 indicators that start with A and C. So you can do a lot of really powerful things with these filters as well. Finally, if you have this ID of this particular indicator, we go to, so instead of going to the indicators endpoint, we go to indicators slash this ID and then you get just this one indicator response. You can then, filters doesn't make sense here, paging doesn't make sense here, but you can specify fields and I would recommend that you do. So let's do display name and code again. And then we have display name and code just for this one particular indicator. Okay, that was a whirlwind tour of the DHS2 metadata API. We didn't talk about data, which you can also access through other endpoints in the DHS2 API system. You can also do things like posting, deleting, putting and patching to edit information in the metadata systems. There's a lot that you can do with this. We call them mutations in the app runtime language and we'll talk about that a little bit more later. You can explore this with, if you use D2 CLI on your local machine in an environment that you can mess around with, you can use postman or curl to test out different commands and see what happens. That's a whirlwind tour. I'm gonna now turn it over to Jose who will talk a little bit about some of the particular API endpoints and particularly ones that are of use to Android and Tracker. But they're also useful, I think, are interesting to know about at least for web application developers as well. Jose, over to you. Thank you, Austin. Super interesting. Now you have say almost everything about the API. I don't know what I'm going to say now. Martin, in any case, let me share my screen. Okay, thank you, Martin. Okay, I'm going to keep it short. So, but I think this also is interesting in order to know the way that we are using the R2 API in the Android development context. So, basically, I'm going to share and, well, Victor already showed this slide yesterday, but I think it's useful to keep it to have it in mind that basically all the Android applications, I mean, the official Android application built by Yo-Yo and other custom Android applications that are using SDK, they don't interact with the API directly, okay? So basically is the Android SDK which the tool that is interacting with the API. This basically means that the developers that are using the SDK, they don't need to know. I mean, it's always useful, very useful to know, of course, but they don't need to use the API if they don't need to. So, that's a, I would say that this is an important thing to understand here, that the R2 SDK, encapsulates the API complexity. So, instead of calling the API in points, you need to just use Java methods calls in your code, okay? So, but in any case, it's useful because some people, many people ask, okay, but what are the API calls that are not covered in Android? It's possible to understand the SDK behavior in order to add more API in points and the answer for all that is yes, okay? And we are going to see that not in this current workshop but in the next workshop that is going to take place in May. So, basically how in the SDK are we selecting the API calls? How are we like interacting with the R2? So, there are like two basic rules. We normally are trying to use the most efficient API calls and for that, that's the reason because we are always in contact with the backend team guys to be sure that we are using the exactly the most performant API calls. So, that means that we try to don't stress the server when there are like many concurrent users and so on, okay? So, that's important and that's a reason because you and the developers, they need to use the SDK. And the reason is like the good balance, we need to have a good balance between the number of API calls. If we have several users or, you know, we need to be able to reduce the number of API calls in order to don't stress the server line. So, for that, we can like use as Austin was explaining the nested operators. So, this means that if you are going, for example, to download the programs, the SDK, what is going to do is like download the programs and all the objects that are related to the programs. Like, for example, the program indicators, the program variables, program sections, and so forth. And also the size of the data returned by the API also is important if we just that we only are using the data from the access to the data that we need. And for that, as Austin was mentioning, we have these two operators, the filters and fields operators, okay? So, right now in the SDK we have been doing this for the last, I would say like two years. So, I think that we have everything there that the developers need. But in any case, as I said before, it's good to know what is the context here, what are the API's goals that have been supported already and what can be extended. So, as I say, as an overview as also mentioned by Austin, so we can divide the number of API goals in order to the metadata or data unlike other that are more generic points, okay? That gives you information about the systems, about the other particular in points that store JSON files and so forth. So, in the metadata from the SDK, we are only using the get. So, that means that we in Android, we are not allowing to post metadata, okay? That's not allowed, only the get for that elements, categories, programs, organization units and so forth. And the eight, of course, yes, we allow the post, of course, otherwise doesn't make sense. And we have like, and we are going to see this in a moment that we have, we are supporting like the three, the three models of the access data values, that is aggregated events for single events with no registration and tracker, okay? So, if we move on in terms of metadata, so this is more or less to give you a context and idea about the resources that we are downloading, right? So, we started like, for instance, like the downloading information about the user that is trying to log in the access to through the Android application. So, with this API code, okay, API me. So, this gives information about the user, username, what are the user roles, user groups, authorities for the particular user, what are the units that the user has access to, for both for searching and for the capture as well. And then we download like a, so everything that is related to the user. Well, after some system info regarding the, what is the version of the access to? You know that the Victor has explained yesterday that the SDK is compatible with different, with six different access to versions there. And this is because we are reading the, what is the access to version exactly using this API code. Okay, so this happens automatically at the moment of data user logs in Android. Okay, and then from there, we are like downloading the org units, category combos, categories, option sets, data elements, also the indicators, everything that Austin was mentioning. Data sets, programs, program stages, rules, relationships, and track and edit types. Okay, more or less, I think that if this is not covering everything that we are downloading from the SDK, it covers the 95%. Okay, and the good news is like you don't need because these calls can be a bit complex because as I said before, this is not only just calling the APIs because also you need in the API, you need to relate it to different objects that are inside of other objects. Okay, so this can be a bit complex. So for the Android SDK users, instead of, they have like a simple methods. So that is v2 metaata module dot download. And this will download as synchronize all the metaata automatically for you. Okay, to give you an example. And as I said, because this can be a bit complex. So if I'm going to go, for example, in mind that we need to download the list of programs that the user has access to. So this can be, okay, I'm going now to, you can still see my screen, right? Yes, yes. Okay, perfect. Okay, so basically this is a list of programs that my user has access to. But of course, we have here the ID, the display name. But of course, this is not what we need more information from the server. Like what are the program stages? What are the program indicators? The styles of the program and all that. So basically the call can be a bit more complex. And basically this is like a kind of summary of the call because it's quite more complex than what I am like copying here. Okay, but to give you an idea, like with just one single call, we can have like all this information here. It takes a bit of time because of the browser needs to render this. Okay, but basically here we have information about every program the user that has created the program, pro-rule variables, the organization unit that this program is linked to and so forth. So basically all this as I said before is encapsulated if you, for under developers when using SDK. Okay, all this complexity. So this is regarding the metadata. Okay, and regarding data, we have just a few endpoints. We have data value sets. Okay, there are, you know, that there are different ways that you can like use for downloading or posting aggregated values to the system, but we are only using this data value sets for aggregated values. We are using events for single event with no registration. We are using API tracker entity instances for tracker data. Okay, and then also for this is related to the previous one when what capability that we have as well is like to search the eyes that are in the server. So this happens now in the COVAX context when people they have, for example, access to the whole country and there are like a 20 million TI is because the TI is every TI is going to be a person in a country. So in this case, we, of course, we can, we cannot download all the data. Okay, so because there is a very small device and the size is very limited in the database. So we then what we do is search online to an online search in order to match what are the target entity instances that the user is looking for with when the user like for a specify a name or an ID or whatever. So this is the, the, the, the API call the target entity things as the last query for, for doing performing this kind of only search. Okay. The way that it works is just going to give you a couple of examples. And it's again, it's quite simple. So that value sets, forget we have one single call per data set. Okay. And in this case, we are passing the four parameters that can be the set ID, the period, the unit and the children. This means that if we're going to specify not only the current of unit, the root of unit, but that the user has access to but also the, the, the ones that are below that particular unit. Okay. So for example, let's do an exercise. So, first, you know that I can use this. Okay. For example, that we can that we can use in order to, for example, the data. Okay. So we have the name. This is the population and this is a yearly database. The, the period type you have it here is the only. Okay. So basically passing these parameters. Okay. So I am downloading like the information that contains that is containing in that data set for the last, I mean, like for these periods that the 2016 till 2021. Okay. So as you see, there are no much information. Okay. So basically, there are no much information. Okay. So basically, there are no much information that takes longer than this, but basically it's a way that we have in order to, to retrieve that is the case when in order to retrieve the data. Okay. And aggregated data. So then in terms of calls, it's as simple as for the user, as simple as calling the D2 method, the object here, aggregated model data download. Okay. And we'll do everything for you. Okay. So basically it's like a compiling all the, all the information of all the data values that are new, regardless the data, the data cells, the periods, or your units and send all of them in, in a single API call. Okay. With this, with this method. Okay. And this is for aggregated the same for, for events. You know, the events for events, the way that we have in order to, to the load events in Android is using the events and point. In, and we only have to specify the units, the program, and then the, the unit mode in this case is a sentence. The sentence means that I'm going to the load events for the, from the root or unit, this or unit, but not only for this or unit, but also for all of the sentence, all the units that are the sentence that are in the lower level in the hierarchy below this, this particular unit over here. Okay. So I am copying this, for example, you, so you will see how this looks like in the API. Okay. And this is the information that is being downloaded in, in Android. Okay. And well, basically I think that we, we are also not downloading in, in a six ML, but we are downloading in as Jason is a matter of adding here Jason here. And it will like change the representation. In any case, again, we can use SDK and this can be automatically done. And for post, it sends all the events in a single API call, regardless the program that they belong to, regardless the third unit. Okay. And last, let me go through the most complicated one that is a target entity instances and for targeted instances, it's a bit more complicated because here this is like the schema. I think that most of you are very familiar with this with the concept of tracker. And also Austin mentioned it a bit for feminists in his presentation, but here we have like, you know, we have a track, we have different levels. We have the target entity instance level that can roll in different programs can be in a malaria program in an HIV program. Okay. And then there are the, for every moment there is a, there are events as well. Okay. So this is more complicated then in order to then retrieve the data from the, from the, from the server. And also this endpoint can be a bit dangerous. If you are downloading many, many targeted things at the same time. Okay. So we need to be very careful when we are like retrieving data that are tracker data. Okay. So in the API endpoint that we are using is API target entity instances. And it's one single call per unit. Again, regardless the program here for, for, for tracker, we download all the TIs that the user has access to. Okay. Well, there is a limit that we can, we are going to see that in the, in the, in the, in the, in the, in the under its rat. Okay. There is a limit of the number of maximum of TIs that you can download. But basically it's that this is important that we are downloading TIs, regardless the program that they belong to. Okay. And this is specifying and resettings in another way, but I don't want to go very complicated with that one. Okay. So basically this is a call. This is a call that is not going to work, but I'm going to show you what is going to render here. Okay. Because in this case, basically what the API scheme is like, all the targeted instances that are, that are below, which are running this below this part, this or unit over here that is Sierra Leone in our server. Okay. But it only gives us information about the, the attributes, okay, names, first name, okay, last name, all that. Okay. But then we need more information because we also need the enrollments and the events. And this is a bit different from the way, because in Android we are trying to get everything at once. Okay. We are trying to reduce the number of API calls that we can do with the, against the server. Okay. And then what we are doing, and this is a sorry about this, but we have this very incredible long API call. Okay. But here what is interesting is like the nested fields, because if one single API call targeted the instances, we are also getting the attributes. Okay. The enrollments, the events. I am not in the relationships because I wanted to keep it very simple, as much simple as I can, because this can create a lot of complexity in the API call. And then the nodes. Okay. So now if I uncopy all these very long piece of API, right here, then I can see that the, I can see the enrollments with the attributes. I can see the, the, the enrollment with events. So in this case, I can see this particular TI has two, two events. Okay. With, with these values. Okay. And of course, if you have to do this by hand is going to be, I mean, quite complicated. It took us a while to get with to this API endpoint. So that's the reason because with SDK, we are encapsulating all this complexity for you. Okay. So you don't need to really know how this, I mean, it's very useful to know how it works, but you have to know that we are hiding this complexity. And so basically this is what we have and well for posts. The way that we work is what we are like posting 10 TI's per call. Because again, we are, we need to be careful about posting many TI's at the same time that we can, the server can have performance issues as well. TI's across all the programs and audience that the user has access to. Okay. The documentation is here with this, within these links. Yeah. Basically, this is what we have in SDK. As you see, we are not using other endpoints like are more related to analytics. I mean, maybe there are others that we can add in the future. Okay. But at least it's, I think it's useful to know what are the context that was, that we are having in the, in the WC in the SDK. Okay. Thank you all for me.