register_rest_route( string $namespace, string $route, array $args = array(), bool $override = false )

Registers a REST API route.

Description Description

Parameters Parameters


(string) (Required) The first URL segment after core prefix. Should be unique to your package/plugin.


(string) (Required) The base URL for route you are adding.


(array) (Optional) Either an array of options for the endpoint, or an array of arrays for multiple methods.

Default value: array()


(bool) (Optional) If the route already exists, should we override it? True overrides, false merges (with newer overriding if duplicate keys exist).

Default value: false

Top ↑

Return Return

(bool) True on success, false on error.

Top ↑

Source Source

File: wp-includes/rest-api.php

function register_rest_route( $namespace, $route, $args = array(), $override = false ) {
	if ( empty( $namespace ) ) {
		 * Non-namespaced routes are not allowed, with the exception of the main
		 * and namespace indexes. If you really need to register a
		 * non-namespaced route, call `WP_REST_Server::register_route` directly.
		_doing_it_wrong( 'register_rest_route', __( 'Routes must be namespaced with plugin or theme name and version.' ), '4.4.0' );
		return false;
	} else if ( empty( $route ) ) {
		_doing_it_wrong( 'register_rest_route', __( 'Route must be specified.' ), '4.4.0' );
		return false;

	if ( isset( $args['args'] ) ) {
		$common_args = $args['args'];
		unset( $args['args'] );
	} else {
		$common_args = array();

	if ( isset( $args['callback'] ) ) {
		// Upgrade a single set to multiple.
		$args = array( $args );

	$defaults = array(
		'methods'         => 'GET',
		'callback'        => null,
		'args'            => array(),
	foreach ( $args as $key => &$arg_group ) {
		if ( ! is_numeric( $key ) ) {
			// Route option, skip here.

		$arg_group = array_merge( $defaults, $arg_group );
		$arg_group['args'] = array_merge( $common_args, $arg_group['args'] );

	$full_route = '/' . trim( $namespace, '/' ) . '/' . trim( $route, '/' );
	rest_get_server()->register_route( $namespace, $full_route, $args, $override );
	return true;

Top ↑

Changelog Changelog

Version Description
4.4.0 Introduced.

Top ↑

User Contributed Notes User Contributed Notes

  1. Skip to note content
    Contributed by abellowins
    //The Following registers an api route with multiple parameters. 
    add_action( 'rest_api_init', 'add_custom_users_api');
    function add_custom_users_api(){
        register_rest_route( 'mmw/v1', '/users/market=(?P<market>[a-zA-Z0-9-]+)/lat=(?P<lat>[a-z0-9 .\-]+)/long=(?P<long>[a-z0-9 .\-]+)', array(
            'methods' => 'GET',
            'callback' => 'get_custom_users_data',

    Make sure that your regex expressions are fine. If the data does not match then the URL will return a 404.
    Some examples are:

    (?P[a-zA-Z0-9-]+) for slug (you can change slug for your custom name)
    (?P\d+) for id
    (?P[a-z0-9 .\-]+) for longitude or latitude

    //Customize the callback to your liking
    function get_custom_users_data($data){
        //get users by market
        $users = mmw_get_custom_users();
        foreach ($users as $key => $user) {
            $market = $user['Market'];
            $long = $user['long'];
            $lat = $user['lat'];
            if( intval($market) === intval(trim($data['market'])) ){
                $result[] = array(
                    'user_login' => $user->user_login,
                    'avatar_url' => get_avatar_url($user->ID),
                    'lat' => $lat,
                    'long' => $long
        return $result;

    Edited to remove an extra ) in one of the regexes. – DevHub Team

  2. Skip to note content

    Args is a named array that usually includes the keys ‘methods’ and ‘callback’.

    ‘method’ defines which HTTP methods are to be processed by the function defined by ‘callback’.

    ‘method’ can be a string of comma-separated HTTP methods or an array of strings of HTTP methods.

    A common practice is to use the WP_REST_Server constants to set the ‘method’.

    WP_REST_Server::READABLE = ‘GET’





    // Get a list of locations.
    // Method GET via wp-json/store-locator-plus//locations/
    // Calls the get_locations method of the current class when the route is matched.
    register_rest_route( 'my-plugin-slug/v2' , '/locations/', array(
    'methods' => 'GET',
    'callback' => array(
    ) );

  3. Skip to note content

    Args , the named array cited above, can also contain an optional ‘args’ array of its own.

    The second args array contains the default arguments, required arguments, validation callback, and sanitization callback that are in place for each argument passed in with the REST request. The key name of this array is the name of the parameter being passed.

    See under the “Arguments” section for more information and examples.


    add_action( 'rest_api_init', function () {
    register_rest_route( 'myplugin/v1', '/author/(?P\d+)', array(
    'methods' => 'GET',
    'callback' => 'my_awesome_func',
    'args' => array(
    'id' => array(
    'validate_callback' => function($param, $request, $key) {
    return is_numeric( $param );
    ) );
    } );

  4. Skip to note content
    Contributed by Mustafa Uysal

    for the non-namespaced routing, call WP_REST_Server::register_route directly.

    add_action( 'rest_api_init', function ( $server ) {
    	$server->register_route( 'foo', '/foo', array(
    		'methods'  => 'GET',
    		'callback' => function () {
    			return 'baz';
    	) );
    } );

    will register foo endpoint without namespace. You can access
    As a reminder, please ensure before registering non-namespaced routes. They can be useful for backward compatibility only.

You must log in before being able to contribute a note or feedback.