 John Hawkins. John has been building things on the internet for over two decades. He found WordPress in the summer of 2003 and has been fully immersed in it ever since. John was the organizer of the first WordCamp conference in Las Vegas in 2009 and has been involved with it almost every year since. He founded and organizes the monthly Las Vegas WordPress Meetup where he's a frequent presenter and has traveled the country speaking at WordPress conferences from coast to coast. Take it away, John. Good morning. All right, I will not be offended if anybody gets up and leaves. At any point during this, you're free to go. So on the third Wednesday of each month in Vegas, I organized the WordPress Vegas Meetup. We are always looking for new presenters, and so I always tell people, you've got an idea. We want to hear you come up and do like a 15-minute presentation. We always get the exact same response. Oh, I'm no expert. I can't go do that. And we're not looking for experts. Like the whole idea behind speaking at a WordPress Meetup is that thing that you've been working on trying to solve. Once you solve it, there's still somebody else who's still trying to get that thing solved. So you getting up on stage and talking about it, whether you're an expert or not, is a great thing. You are actually going to help somebody, I promise you. Today, I'm going to be talking about, let me just give you a little bit of an introduction to the WP Rest API. Hello, my name is John, and I am no expert. But I did stay at a Holiday Inn Express last night, so let that go in for me. This right here is a talk where I'm just going to tell you what we're going to cover today. We're going to talk about what the heck the WP Rest API is. Anybody have no idea what I'm talking about when I say the WP Rest API? Awesome. My sister over there. That's great. So we're going to talk about the WP Rest API. I said I'll tell you a bit about what it is. I'm going to tell you about how I got into it and the problem that I was trying to solve that kind of forced me to learn about the WP Rest API. And for me, when I'm trying to figure something out, it's always a really like you need to have kind of like a real world problem to solve. So I'm going to talk about what I would have done previously before using the Rest API, how I would have tried to solve this issue, which I did try to do previous to using it, how I would have done it before using the Rest API, then how I use the Rest API for fun and profits. And at the end, I'll talk about some tools that I used that really were basically the difference between actually making this thing work and not within a reasonable amount of time. And then because I'm not going to be able to teach you an entire presentation, I'm not going to teach you the Rest API in 45 minutes. I'll just show you some other places that you can go and check out. So what is the WordPress Rest API? So I'll just let you read that. So the Rest API is basically a way of passing data back and forth into WordPress and then having it kind of spit out data. It enables developers to create and read and update WordPress content from client-side JavaScript, which I don't write JavaScript, by the way, and from external applications, even those written in languages beyond PHP. I'm a PHP developer, so I typically would build everything that I do in PHP. JavaScript is a thing that I keep saying I'm going to learn. That's on my list. One day. One day. So when you're talking about the Rest API, there are these things called methods. For me, these are the things that you can do with the Rest API. The Rest API is about you can get data. So you can retrieve data from a server. You can post data. So if you wanted to send data to a server, you can put data, which is like changing or updating data on the server. So if you wanted to make changes to the title of a post or to if you've got to see a custom post type and you want to do inject some new data, you can do that through a put or you can delete. So I no longer need that item. I'm going to go in there and I'm going to just delete it. There are some other Rest API terms that if you were going to really get into digging in and learning the Rest API, these are some other terms that you're going to run into, routes and endpoints and requests and responses and schema and controller classes. And I'm going to talk about maybe one or two of those, this entire session. And but these are some other ones that you're going to run into. This is probably a good point of just getting, so when you're going and looking things up, these are going to be some terms that you're going to run into. So let's talk about the problem that I was trying to solve. I had a client and it always starts like that, right? I have this client with this crazy idea. So the central website was built in WordPress. Data was going to be being posted in from a third-party site. I was going to collect some of that data. I was going to process some of the data, data then make some decisions based on the data that came in. And then I was going to post data out to a third-party location, get some data back, blah, blah, blah, and then display the appropriate information to the client or to the website visitor at the end. And it looked kind of like this. So the yellow block, the yellow box up there was somebody else posting data into us. All those blue boxes in there are WordPress, either storing data, making a decision, and then doing something with the data. And then that orange block is us kind of posting out to another spot, blah, blah, blah. If this had been it, if this had been the entire project, I still wouldn't have needed the REST API. This was great. I had all of this. We had it all built. And then, of course, the client says, oh, by the way, there's this one other little thing. There's always that one other little thing. This process was they were taking leads. Leads were kind of coming in, and then they were trying to qualify those leads. And then they had a call center. And so what the call center was doing is we would send the data, and it would go into the call center queue. And then the call center would do this, where they would then call and get the person on the phone. And as soon as they got that person on the phone, they needed to get real-time data about who the person was that they were going to be talking to, and none of that who the buyer was. And all of the buyer information all had to happen in real time. It wasn't like I could have done it all at the beginning and then just thrown it all at them initially. No, they couldn't know any information about who the buyer was until it was happening in real time. So that was fun, OK? I'm like, that's fantastic. I have no idea how to do what you're asking me to do. Let's figure it out. So talk about a little bit about how I would normally solve that issue. And so for me, call it the imposter syndrome. But I've always kind of considered things like the REST API. That's for real developers. I just kind of tinker around with PHP a little bit. And it looks like this when I type. So I would always typically fall back to methods that I'm familiar with. And so I'm going to show you a couple of those options. And the first one is, well, I'm going to build a shortcode. Shortcodes are fantastic. They are super powerful, and you can do a lot of stuff. One of the things that they do very, very well is hide chunks of code from your clients and don't let them screw things up when they're in the editor, which is a lot of fun. So if I was going to do something with the, anybody built a shortcode? This is a really simple process, right? I'm going to create a shortcode, and it's going to be called process the data. And once, if a page loads and that shortcode is on there, it's going to run this particular My Shortcode function. And then in there, all I'm going to do is I'm going to do something really simple. We're going to check to make sure that I'll make the slides available. You don't have to do that. You can try to figure out what that MD5 hash is. It actually says, your mom, kind of like that. I don't know why. You need something, and I'm like, your mom. So in here, this is like a really simple way of kind of going about it. So I'm just checking to see if they've sent me the proper secret code. And then if they have, did they send me for an ask, or are they sending me an update? Because there's kind of two different processes that they needed to do. And based on that, I'm going to just run one of two functions. Piece of cake, no problem. You throw it up onto, you create a WordPress page, you throw your data in there, and it just, anytime somebody goes to the process-data page, it's going to run my script and try to then do something with it. Great. There's challenges. The first one is a little bit of a silly challenge, but for me, it's those nagging things that kind of bother me about ways that we kind of solve things. And it's as simple as this. That process-data is now a page that exists on this person's website. So if they don't know any better, that page can get indexed. And now that can just be a page that gets, people are like, oh, I'm going to click on that as a search result. They're going to get nothing, or they're going to get some weird error. So obviously, there's ways around it, but it's just, it's one more thing. And not only that, now you've got, if a client's in there, and they go, what does process-data do? Delete. Well, process-data doesn't do anything. Now, thanks, pal. But yeah, so it's just kind of a silly one. The bigger problem with the, with it was the, it's, you know, a shortcode is mainly used for, yeah, I can process data behind the scenes, but the idea is that it's going to then display some sort of a response on the screen, which obviously for my call center, that wasn't really going to be helpful, because they didn't need to see it. They needed to get that data and bring that data back into their system so that they could actually do something with it. So as easy as that would have been, shortcodes were kind of out of the question. So option two, I am sure that there's actually a technical term for what I'm about to show you, but I've always just called it the listener. So what is the listener? The listener is basically, it looks a lot like the code from the shortcode. The only difference is, I've kind of created this as an action that is hooked to the init function inside of WordPress, which super simple. Anytime WordPress goes to load, it hits that init area and it says, great, as soon as the init happens, I'm going to go and process this data. The problems with this are, this is going, the init runs on every page load, whether it's front end or back end. Obviously I could have probably found a different hook to connect it to. It didn't have to be on init. It could be on something different. But still you kind of run into that same basic problem, which is it's going to run all the time on a certain set of pages. And since I'm looking for posted data, that means if somebody is going to fill out a contact form or fill out any sort of form on your website, this process was going to then run and try to process data. And not that it's the end of the world, but it's just one more thing and it's not clean and there should be a different way. There was. And we'll talk about that. And also, by the way, that the biggest problem with this one would have been that, with this one or the shortcode really, is I would have needed to build my own, oh, my notes are like on the next screen, so the challenge is, the biggest problem was I would have needed to design and build a way of packaging up that data and then delivering it back to the call center. And that's a pain. It's a pain that it was going to be a lot of extra code that I would have had to have written and maintained. And if they ever changed anything, I would be the one who had to kind of go and do that. So both of my kind of previous here's how I would do it, we're kind of out the window. And so that's when I'm like, all right, let's just go take a look at the REST API. So the REST API to the rescue. So like anything new, when I first started messing with the REST API, I was overwhelmed. I'm like, this just seems like it's so big. There's so many different things you can do with it. Again, this is for real developers, but so let's, we're gonna kind of take this, we're gonna strip it down and we're going to talk about the absolute basics of getting into this because all of the challenges that I had, we're kind of already taking care of force in with the REST API. So the way that it works is you're going to create a route and a route is basically like, you're gonna tell people, this is where you're gonna go. This was actually another one of the big things was because I didn't wanna have people going to process-data. So these routes, they exist in WordPress and I'll show you a couple of examples. These exist on your WordPress website right now and you may not even know that. So if you use pretty links, just pretty permanent links, you can go to slashwp-json, you can do this on your own website right now and you are gonna get a big JSON package of data. And you can do a ton of stuff with that data or nothing, it just exists, it's there. But somebody could, the idea behind that, if you think about like a desktop tool, you wouldn't necessarily, like a desktop tool if you wanted to build like a Mac native app, let's say, you can have that and reach out to these API points and all of that data, WordPress is already just kind of serving you that data, you can kind of grab it and then display it and do whatever the heck you want with it. So this is what it looks like if you've got pretty permanent links and this is what it looks like if you don't use pretty permanent links, the obvious answer here is use pretty permanent links because it's just such a clean process for doing that. So WordPress has a number of built-in endpoints and I'm not gonna, there's a long list of them but I mean you can get like posts and pages and authors and pretty much everything. If it exists inside of kind of like core WordPress, there is a JSON endpoint for it. So like this one up here, wp slash v2 slash posts, this is going to give you, I'm not sure if it gives you all of the posts or if it only gives you the first 10 like a per page thing, but it's gonna give you a bunch of posts and so it doesn't really matter. Does it give them all? No, if I default it gives the number of posts. The per page? Yeah. Okay, so you would by default, you would see the latest 10 blog posts. One of the other things that you can do with these endpoints, which is kind of fun and I'm gonna talk about it about this much is you can see like I've added slash one, two, three under the end of that API, under the end of that endpoint and what this will do is this will actually just give you the information for that particular post, post ID number one, two, three. So again, if you think about that idea of building like a Mac native desktop app and you said first I wanna display a list of all recent posts, you would go to that other API point or if you go, oh, they've clicked on a link, now I just need to grab all of the data for that one particular post, you can do that too and that's all built in. When you're building your own API endpoints you can do this exact same thing and I have a slide that'll show you the code and it's a couple of slides ahead but this actually ends up using some like regular expression stuff and if you thought or if me, imposter syndrome here, thought that the idea of using the rest API was above me, regex is, that's in a different, not even close. Do we have any questions at this point? Let me just stop. I'm gonna get another drink and if we have any good questions, good jokes. All right, good, I like it. So what is this going to look like? Okay, so this is me creating a route. This is a very simple route. When you're doing this route, the way that this works is I'm registering a new route and all I'm doing is I'm basically telling WordPress, you should start to expect new things to happen at this URL. So register, rest route, this is gonna be that slash wp-json slash client name slash v1, you can put whatever you want there, it doesn't really matter, you can put anything you want and then slash data handler and it's at the end of that where that data handler is and I think it's actually, it's on, it's that slide so you can see that little question mark p slash d, that's the regex stuff that is actually pulling that one little piece of data. So, all right, so this basically tells WordPress we're gonna create a new route, it includes a namespace, that's that first part there, that's called the namespace, then the second part is actually the route. So if I wanted to, I could use different, where that is, I could create different elements inside of there for what types of things that I wanted that API to do. So for me, I was really trying to keep this very, very simple. So all of my stuff is actually just live, so I don't care whether they're going to be, whether they're sending me the data for the first time or if they're later sending me one of those update quests or like some of them they do an ask and some of them they do an update. If they do an ask, I need to go do all of my big lookups and then send them back a bunch of data. But later on, after they've actually talked to that person, they will do an update. So they'll say, hey, we talked to that person and it's a go or they talked to that person and or the, I didn't talk to that person, I tried to and I need to call them back at 7 p.m. And so they might send me one of those. So I could have created separate end points for each one of those and just assumed, hey, anytime anybody hits this end point, I know that this is what they're trying to do. But for me, I was trying to make it easy in two ways. One, I was trying to make it easy for me to keep all of this in just one little bucket. And two, I was really trying to make it easy on the person on the other end where I just said, when you send me all of the data, you can just send me a modifier in there, like a status or a mode. And I'll show that to you in just a second. So in here, based on this setup, our URL would end up looking like this down here. So wp slash JSON, client name, v1, data handler. So now WordPress knows that that thing exists and is gonna just sit there and wait for data to be coming in only on this URL. If they were to post to the main page of WordPress, WordPress is like, I don't know what you're trying to do. I don't care. And it's gonna just ignore it, which means no extra processing behind the scenes. So somebody fills out a gravity form, whatever, none of that matters. My code is in a separate space. And it is really unlikely that the client is gonna go break this, because they, first off, the client has no idea this even exists. They just know that it works behind the scenes. They're like, hey, great. So that's why this is another really great way of kind of going about that. All right, so I'll tell you, oh yeah, the regex. This is a whole slide all about regex. So if I wanted to, I could say data handler 456. So they were gonna send me an update about post 456. This was overkill for my project. It might not be for yours. Or actually, this is probably a really, this is one of those things where if I were to probably test it, I'd go, shit, that was easier than I thought it was gonna be. I should have done it that way. What this happens, the last thing you're gonna see right here is the callback. So what happens is when data gets posted to there, if you were to try to go to this URL, which obviously don't because I don't own your site.com, which would be really a cool domain name down. But if you were to put that into your address bar, in the address bar, that is a get request as compared to a post request. So even if you were to try to do this on the actual website, you would just get, hey, I think the response is something like no route is set up or no endpoint is set up. So WordPress is gonna basically say, I was expecting a post of data. You tried to send me a get request, go away. I don't care what you're trying to do, just I'm not gonna do anything. But again, this is great because there's no real processing power. It got to just right there and said, I don't know what you're talking about, moved on. So here's our URL. What it's gonna do though is if you do pass that data in and it goes to that right URL, then it'll hit my callback function. So now my callback function is really pretty simple. Grab some data and it takes this data and it's gonna do that request. WordPress has a lot of built in functions that make kind of dealing with the data that come in. Super simple. So this get JSON params, I'm taking and I'm turning that into, I'm putting all of that into this little one variable called data. And all of that data just comes in as a nice little array and now I can really do whatever the heck I want with it. So you see I've kind of created a, yeah, so this is really just the shell of the function and some super handy functions. Da, da, da, da, da. They'll take it. Yeah, I already said all of that. Great. Okay, so let's kind of build a little bit further. So after I've got my data, the next thing that I'm gonna do is which allowed keys. I'm gonna check to see that they are sending me their proper key because I don't, if it's not my call center sending data to this, let's just say randomly somebody figured out how to find my JSON route or my REST API route. I wouldn't want them, just anybody being able to send me updates for any of my posts. I don't want them to be able to change the status of a client's call records. That would be bad. So because I only have one call center ever sending this in, I just hard-coded it. So I basically said, here's an allowed key. Did the data match it? It did? Great, I'm gonna keep processing. It didn't? Good, go away. If this particular client were to have a whole bunch of different call centers or folks that were potentially going to pass in data, I would probably create a user for each one of those folks and then attach this as metadata and then do a lookup as the data was being processed. But again, trying to keep it simple, trying to not make it overkill for what was needed on this project, I just kept it super simple. And then basically I'm gonna just strip out, I'm gonna grab some data and you can see I'm kind of escaping all the data. I wanna make sure that they're not gonna send me anything that is gonna be harmful. And I just kind of extract some variables and made them very easy to, so that when I'm doing stuff later on in the code, they're easy. So this is their key, this is their ID, this is that mode that I was talking about, whether it's gonna be an ask or whether it's gonna be an update. And then if it is, one of the modes has a lead status, which is just a number one to eight or nine, like different statuses for what that is. So I'm gonna just kind of create those as variables and then I can use them a little bit further down in the process. And then down below that, I'm gonna just start doing some checks. So I think the first one is, yeah, so is the key, is the key that they sent me, does it match that allowed key? This is fun. Remember I was talking about how WordPress has some built-in functions and one of the best ones is this rest ensure response. This is the absolute life saver. If I wasn't, back when we were talking about the other way, like that, building a listener and I said that I would have to figure out a way of packaging up that data and then sending it back to the call center and I would have to formulate what that stuff would look like. Yeah, I don't have to do that now. All I have to do is say I'm gonna return this particular function and then I just make an array. And so the array can literally be anything that I want. So I've got a document that I told the call center you can expect to get back a couple of different things. You can get a code. That code is gonna be whether or not it's like, I'm gonna tell them what the error is. It was an invalid key. So if their key was wrong, I'm gonna tell them, hey, you sent me the wrong key and I can send them a message and I can do a status. So all of my error statuses are 100. Other statuses are like 200, 300 and 400, et cetera. So yeah. This is, I mean, the API key is different. What? I did change some stuff. So it's not 100% but yes, that is not actually a syntax error. So it has to be exact. So not equal, so it's not equal and then not exact is what this is. So yeah, good, yeah. Not actually wrong, sweet. By the way, finding a syntax error in my code, not a stretch. Like, where is it? And we're this far in and you only found one so I thought we're doing pretty good. Being nice, cool. You guys are all right. That's funny, I was thinking, did I run this code? So then there's a couple of other checks. That was so good. I do a couple of other checks to make sure. I created an array of the different modes that I was kind of going to be expecting and then I just checked to see if it's one of those modes. Great, no big deal. And then the post data. Oh yeah, do we have, I do a look up at this point to see if the ID is in the database. Oh yeah, it is, okay, great, you can go through. If not, go away. So I'm doing all of these checks before I do any of the actual processing. I'm just trying to figure out, I'm gonna kick them out any point that doesn't make it. Like anything that could be potentially wrong, I'm just kind of doing it the top of it and then down at the bottom is kind of where the magic happens. So I'm gonna read this because I wrote a lot of text. So when the call center gets the lead on the phone, they ping the rest API with a mode of ask. So first we do the global status just in case the step fails. If not, I do this, blah, blah, blah. I already said all of that. That was a whole slide to go. Let's see, what do we do here? Okay, so they're doing an ask. So the mode comes in as an ask and I said, great, I'm gonna immediately, I'm gonna do an update status, I'm gonna do an update post meta. I'm gonna create a global status basically saying, now I will tell you, I'm returning all of this stuff in real time and when I say it's real time, I think they're getting it back in like a quarter of a second. It's ridiculous how fast it is. So the idea of doing this update post meta at the very, very top is kind of silly because that exists for about a quarter of a second. It's in there and then I'm gonna do another one a second later. But I actually do this on purpose because if for whatever reason, when I post out to the other folks and I'm supposed to be getting data back, if for whatever reason something breaks, I'll know about it because the global status should this, yeah, pending. If somebody were to load up the list of all of the different leads and they see something that is marked as pending, well, there's a problem. Something broke somewhere along the way. In a future version of this, my idea was that I would create a little button like on the dashboard so when they're looking at their list of all of their leads, if they see any that say pending, there would be another button like right next to it that is like, okay, just reprocess because I would have already had all that data. I would already have everything that they had sent in kind of stored and ready to go. But for whatever reason, the internet was just broken for 30 seconds and probably because of my typo on that previous page, they would see that it was pending and I'd be able to click it and then reprocess the data. I never got to that point. By the way, none of this actually launched and the client stopped. Like I built all of this and then it didn't welcome to client work. He built all this fun stuff. Oh, I got paid. Oh, I got paid. Yeah, that happens first. So once I did that, then I'm doing a find a buyer. The find a buyer is actually the piece that is going out and calling the third party system that returns all the buyer information to me. And when they do that, I'm basically getting back an array. So if I don't see an array, then I basically know that there was no buyer and I returned that back to the client or to the call center and then they get that awkward thing of, hey, I know that you were trying to do that. We don't have a buyer. So I've got nobody for you to talk to by click. So, whoops. And then you can see I'm doing that update post meeting again, whether it was a sold lead or whether it was a no buyer. So, real simple stuff. Okay. Oh yeah. So this was, I'm not gonna really get into what the folks were sending me back, but this is basically what it looks like. So when they send it back, because I don't wanna have to be the one who's kind of processing all of that data and turning it into something fancy, all I'm doing is turning it in an array. So here's the buyer data is an array, which is the status is gonna be success. And then I'm looking up in our database because I store all of that data again. Buyer data is their name, their phone, email, the URL. And then I'm just returning that back with that nice little function that rest return response. And I just send them all the information. Super simple. Yeah, and then this is what I send back to the call center. Thank you. Yeah, so on their side, this is now just a small little chunk of JSON data that they can get and then they can process the same like I was processing it on the other side. They know that they're getting ready to call Tyler Durden. Oh, there's a lot of talking. All right. Questions so far. You guys all ready to go do this? Yes. I'm gonna go back to the beginning. Yeah. So what I do, typically, so the question was, I've written all this code. Where does it live? Does it live inside of functions.php? For me, what I typically do, anytime I'm building something like this for the client, I don't wanna tie it to their theme. So I'm not gonna put it in the theme because the whole idea is this should really kind of be agnostic to the theme. And it is, this has nothing to do with the theme. So what I'll do is I'll actually create a very simple plugin. I almost, for all my clients, I typically will create something called a core functionality plugin. And so then I have a spot that is just a functions file or in this case, it's a series of files that is part of a plugin. And so they can kind of go activate it or deactivate it. Hopefully they don't deactivate it. That would be bad. Thank you. MU plugins, I could do that. I don't, because then I can never remember it's there. Then forget about it. How does this even work? I don't even know. Oh, question is, what is my text editor? That is, no, that's VS Code. Yeah, this is VS Code. Yeah, it's VS Code and I have an absolute crap ton of extensions. And I would tell you that I'm really smart and figured out all these extensions to use. That is not the case. Yes, it's super handy also, and you can immediately go, oh, that's where it's indented wrong. Yeah, it's an extension for VS Code. If you want, you can email me and a buddy of mine has a whole list of extensions and that's what I did. VS Code, Mac and Windows? Everything, right? Mac, Windows, Linux, yeah. I could try. Yeah, I'll put these online. Yes, yes, maybe. VS Code is free. I love it, yeah, yeah. VS Code is awesome. And I actually just switched to it. I've been a sublime user for years and years and years. And at my previous company, they were all switching to VS Code. Oh, so good. It's really, it's really good. It's got Git built right in. It's fantastic. All right, so let's talk tools. When you are dealing with JSON data, whether you're the one creating it or whether the one you're consuming it, it looks like a big blob of text. Like this is, oh, by the way, I think this is if you go to slash WP JSON. Like this is, that's what you're gonna get. And like it is just a crap ton of just useless data. There is a Chrome extension called JSON formatter that just automatically has a little toggle over there and you can switch back and forth into this pretty view and actually see what you're getting. We have five minutes, so if you have questions, get ready to ask them quickly. So yeah, just super simple. Oh, do they? Oh, automatically? Nice, Chrome does not. Chrome just was like, here you go. Pfft. Just, ugh. This plugin, Postman. Anybody ever heard of Postman? Yeah, this thing is fantastic. This is honestly the difference between me building this project and not building this project. I'm gonna just show you what this thing does, testing your API. Okay, so this is the screen and let me see here. So up at the very top, I'm writing the URL that I want this to be tested at so you can see that I've got it going to my example.local and then the endpoint that we've been talking about this entire time. And then in the body, I've created just a little bit of a JSON package which is the key, the mode and the ID. So this is the client's key, or I mean the call center's key, what mode they wanna, I wanna test them doing an ask and then an ID and then you hit the blue button up there that says send, it sends it and it shoots you back this little package of data or it sends you back an error message which it sends you back a lot of error messages before you actually get it to send you back actual data. A lot of error messages, yes. But being able to just hit that send button, make one change in your code, hit the send button, make one change in your code, hit the send, like it is a repeating thing for like four days. Oh shit, like there's data. It's the best, it is the absolute best. So Postman, they have, it's free. They do have some paid tiers. I liked it so much I wanted to just go and purchase it but none of their paid stuff like applied to me at all because it's kind of like team related stuff or none of it applied. So I gotta give money some other way I guess. And here's the learn more which is I'm gonna just give you one URL other than Google and some searching. Developer.wordpress.org slash rest-api. Everything under the sun is right there. Like you can go, it'll give you any of that. Any questions? Yeah. I just want to mention how useful is the rest API especially if you are an agency that work with different clients, with different hosting companies, with different WordPress versions, different plugins. Once we create a rest API that help us to give us the version of the WordPress version of plugins because sometimes you cannot even access to the through SSH to run some commands in the CLI. So it give us all the information that we needed and then we use it in our own custom dashboard so you can have all the information of all your clients because all the clients have different needs, have different servers, different anything. So it was very useful to have in one dashboard all the clients. That's awesome. I'd love to see a screenshot of that. That'd be fantastic. Yeah, it is. As soon as you find the need or the data that you have access to get from all these different locations, then it's really just a matter of like, once you've got all this data, what am I gonna do with it? Building at your own internal dashboard is awesome. I love that idea, for sure. Robert, did you have a question or a statement? Or over here, go ahead. Now that you've done this, have you found other use cases or have you started redoing anything? Has this created a whole new avenue for you? So I have a regular day job. Where I also build WordPress stuff all day, which is fun. So I haven't had anything where I'm just like, oh, I'm gonna go back and do that thing. But I do now at least consider it an option, something in my tool bag where I'm like, all right, well I could at least run the idea where before it was, it did. It just felt like it was, that's something that other people do. I don't do that, somebody else does that. But yeah, like she was saying the idea of creating a dashboard, of pulling in your data from a whole bunch of different locations. Robert, I think you're gonna ask me one more question. One more question. I have a whole more statement than a question. If you're doing any Gutenberg work with custom websites, you have to have showing rest, that's the truth. So it kind of ties in with this. That's true. It took me half an hour to find that. Yeah, yeah. Awesome. All right, well I'm not going anywhere. I'll be here all day. So if you have any other questions, hit me up. Otherwise you can find me at johnatvegaskeek.com. Thank you.