diff --git a/rpc/interface/Cargo.toml b/rpc/interface/Cargo.toml
index feb1aff..42d1055 100644
--- a/rpc/interface/Cargo.toml
+++ b/rpc/interface/Cargo.toml
@@ -22,7 +22,6 @@ anyhow     = { workspace = true }
 axum       = { version = "0.7.5", features = ["json"], default-features = false }
 serde      = { workspace = true, optional = true }
 tower      = { workspace = true }
-thiserror  = { workspace = true }
 paste      = { workspace = true }
 futures    = { workspace = true }
 
diff --git a/rpc/interface/src/route/bin.rs b/rpc/interface/src/route/bin.rs
index 45447ca..90d06c8 100644
--- a/rpc/interface/src/route/bin.rs
+++ b/rpc/interface/src/route/bin.rs
@@ -5,7 +5,14 @@ use axum::{body::Bytes, extract::State, http::StatusCode};
 use tower::ServiceExt;
 
 use cuprate_epee_encoding::from_bytes;
-use cuprate_rpc_types::bin::{BinRequest, BinResponse, GetTransactionPoolHashesRequest};
+use cuprate_rpc_types::{
+    bin::{
+        BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksRequest, GetHashesRequest,
+        GetOutputIndexesRequest, GetOutsRequest, GetTransactionPoolHashesRequest,
+    },
+    json::GetOutputDistributionRequest,
+    RpcCall,
+};
 
 use crate::rpc_handler::RpcHandler;
 
@@ -66,8 +73,16 @@ macro_rules! generate_endpoints_inner {
     ($variant:ident, $handler:ident, $request:expr) => {
         paste::paste! {
             {
+                // Check if restricted.
+                if [<$variant Request>]::IS_RESTRICTED && $handler.restricted() {
+                    // TODO: mimic `monerod` behavior.
+                    return Err(StatusCode::FORBIDDEN);
+                }
+
                 // Send request.
-                let response = $handler.oneshot($request).await?;
+                let Ok(response) = $handler.oneshot($request).await else {
+                    return Err(StatusCode::INTERNAL_SERVER_ERROR);
+                };
 
                 let BinResponse::$variant(response) = response else {
                     panic!("RPC handler returned incorrect response");
diff --git a/rpc/interface/src/route/json_rpc.rs b/rpc/interface/src/route/json_rpc.rs
index bf3d937..7efb851 100644
--- a/rpc/interface/src/route/json_rpc.rs
+++ b/rpc/interface/src/route/json_rpc.rs
@@ -50,7 +50,9 @@ pub(crate) async fn json_rpc<H: RpcHandler>(
     }
 
     // Send request.
-    let response = handler.oneshot(request.body).await?;
+    let Ok(response) = handler.oneshot(request.body).await else {
+        return Err(StatusCode::INTERNAL_SERVER_ERROR);
+    };
 
     Ok(Json(Response::ok(id, response)))
 }
diff --git a/rpc/interface/src/route/other.rs b/rpc/interface/src/route/other.rs
index 129ddd5..3ff8448 100644
--- a/rpc/interface/src/route/other.rs
+++ b/rpc/interface/src/route/other.rs
@@ -82,7 +82,9 @@ macro_rules! generate_endpoints_inner {
 
                 // Send request.
                 let request = OtherRequest::$variant($request);
-                let response = $handler.oneshot(request).await?;
+                let Ok(response) = $handler.oneshot(request).await else {
+                    return Err(StatusCode::INTERNAL_SERVER_ERROR);
+                };
 
                 let OtherResponse::$variant(response) = response else {
                     panic!("RPC handler returned incorrect response")
diff --git a/rpc/interface/src/rpc_handler_dummy.rs b/rpc/interface/src/rpc_handler_dummy.rs
index 06fa460..0b01835 100644
--- a/rpc/interface/src/rpc_handler_dummy.rs
+++ b/rpc/interface/src/rpc_handler_dummy.rs
@@ -3,19 +3,20 @@
 //---------------------------------------------------------------------------------------------------- Use
 use std::task::Poll;
 
-use cuprate_rpc_types::{
-    bin::{BinRequest, BinResponse},
-    json::{JsonRpcRequest, JsonRpcResponse},
-    other::{OtherRequest, OtherResponse},
-};
+use anyhow::Error;
 use futures::channel::oneshot::channel;
 #[cfg(feature = "serde")]
 use serde::{Deserialize, Serialize};
 use tower::Service;
 
 use cuprate_helper::asynch::InfallibleOneshotReceiver;
+use cuprate_rpc_types::{
+    bin::{BinRequest, BinResponse},
+    json::{JsonRpcRequest, JsonRpcResponse},
+    other::{OtherRequest, OtherResponse},
+};
 
-use crate::{rpc_error::RpcError, rpc_handler::RpcHandler};
+use crate::rpc_handler::RpcHandler;
 
 //---------------------------------------------------------------------------------------------------- RpcHandlerDummy
 /// An [`RpcHandler`] that always returns [`Default::default`].
@@ -45,8 +46,8 @@ impl RpcHandler for RpcHandlerDummy {
 
 impl Service<JsonRpcRequest> for RpcHandlerDummy {
     type Response = JsonRpcResponse;
-    type Error = RpcError;
-    type Future = InfallibleOneshotReceiver<Result<JsonRpcResponse, RpcError>>;
+    type Error = Error;
+    type Future = InfallibleOneshotReceiver<Result<JsonRpcResponse, Error>>;
 
     fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
@@ -100,8 +101,8 @@ impl Service<JsonRpcRequest> for RpcHandlerDummy {
 
 impl Service<BinRequest> for RpcHandlerDummy {
     type Response = BinResponse;
-    type Error = RpcError;
-    type Future = InfallibleOneshotReceiver<Result<BinResponse, RpcError>>;
+    type Error = Error;
+    type Future = InfallibleOneshotReceiver<Result<BinResponse, Error>>;
 
     fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))
@@ -130,8 +131,8 @@ impl Service<BinRequest> for RpcHandlerDummy {
 
 impl Service<OtherRequest> for RpcHandlerDummy {
     type Response = OtherResponse;
-    type Error = RpcError;
-    type Future = InfallibleOneshotReceiver<Result<OtherResponse, RpcError>>;
+    type Error = Error;
+    type Future = InfallibleOneshotReceiver<Result<OtherResponse, Error>>;
 
     fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
         Poll::Ready(Ok(()))