SQL Server 2025: Calling External REST and GraphQL APIs from T-SQL (Part 10)

Introduction

SQL Server 2025 introduces one of the most forward-looking features in its history: the ability to call external REST and GraphQL endpoints directly from T-SQL using the new stored procedure:

sys.sp_invoke_external_rest_endpoint

This fundamentally expands SQL Server from a relational engine into a hybrid data-integration platform capable of:

• Calling REST and GraphQL APIs
• Triggering Azure Functions or Logic Apps
• Sending data to machine learning models
• Pulling data from external services
• Integrating directly with microservices
• Exchanging JSON and Base64 payloads
• Automating workflows from inside stored procedures

In this article, we’ll break down how it works, how to call authenticated endpoints, how to send and receive JSON, error handling, performance considerations, and real enterprise use cases.


What sp_invoke_external_rest_endpoint Does

This new stored procedure makes HTTP(S) calls accessible from inside SQL Server:

Supported methods:

• GET
• POST
• PUT
• PATCH
• DELETE

It accepts:

• URL
• Headers
• Query string parameters
• JSON payloads
• Returned JSON, XML, text, or binary
• Timeouts
• Error metadata

This bridges SQL Server with the outside world without writing CLR code or using xp_cmdshell.


Basic Syntax

EXEC sys.sp_invoke_external_rest_endpoint
    @method = 'GET',
    @url = 'https://api.example.com/status';

If the API returns JSON, SQL Server will return it as NVARCHAR.


Example: Simple GET Request

EXEC sys.sp_invoke_external_rest_endpoint  
    @method = 'GET',
    @url = 'https://api.github.com';

This is the simplest form.


Example: GET with Headers

EXEC sys.sp_invoke_external_rest_endpoint  
    @method = 'GET',
    @url = 'https://api.example.com/data',
    @headers = '{"Accept":"application/json"}';

POST with JSON Payload


DECLARE @payload NVARCHAR(MAX) = N'{
    "requestId": 1025,
    "action": "process"
}';

EXEC sys.sp_invoke_external_rest_endpoint  
    @method = 'POST',
    @url = 'https://api.example.com/ingest',
    @payload = @payload,
    @headers = '{"Content-Type":"application/json"}';

Using BASE64 with REST Calls

From Day 5, Base64 encoding is essential for authentication or binary transfer:

DECLARE @authHeader NVARCHAR(MAX) =
    'Basic ' + BASE64_ENCODE(CONVERT(VARBINARY(200), 'user:password'));

EXEC sys.sp_invoke_external_rest_endpoint  
    @method = 'GET',
    @url = 'https://api.secure-service.com/data',
    @headers = '{"Authorization":"' + @authHeader + '"}';

This is a common pattern when interacting with:

• OAuth services
• API gateways
• Basic-auth protected endpoints
• Machine learning model scoring services


Example: Sending JSON From a Table

DECLARE @payload NVARCHAR(MAX);

SELECT @payload = (
    SELECT TOP 1 *
    FROM Orders
    FOR JSON AUTO
);

EXEC sys.sp_invoke_external_rest_endpoint  
    @method = 'POST',
    @url = 'https://api.example.com/order/process',
    @payload = @payload,
    @headers = '{"Content-Type":"application/json"}';

Handling Returned JSON

To handle the result:

DECLARE @response TABLE (JsonText NVARCHAR(MAX));

INSERT INTO @response
EXEC sys.sp_invoke_external_rest_endpoint
    @method='GET',
    @url='https://api.example.com/info';

SELECT * FROM @response;

You can then parse it:

SELECT JSON_VALUE(JsonText, '$.status') AS Status
FROM @response;

Calling Azure Functions

Azure Functions often require POST and authentication.

Example:

EXEC sys.sp_invoke_external_rest_endpoint
    @method='POST',
    @url='https://your-function.azurewebsites.net/api/ProcessOrder',
    @headers='{"x-functions-key":"<your-key>","Content-Type":"application/json"}',
    @payload='{"orderId": 1001, "priority": "high"}';

Calling GraphQL from SQL

Example GraphQL query:

DECLARE @payload NVARCHAR(MAX) = '
{
  "query": "query { product(id: 100) { name price } }"
}';

EXEC sys.sp_invoke_external_rest_endpoint
    @method='POST',
    @url='https://api.example.com/graphql',
    @headers='{"Content-Type":"application/json"}',
    @payload=@payload;

Error Handling

The stored procedure returns structured error responses.

Example TRY/CATCH block:

BEGIN TRY
    EXEC sys.sp_invoke_external_rest_endpoint
        @method='GET',
        @url='https://api.invalid-url.com';
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER()     AS ErrorNumber,
        ERROR_MESSAGE()    AS ErrorMessage,
        ERROR_LINE()       AS ErrorLine;
END CATCH;

Timeouts

You can configure:

@timeout = 30  -- seconds

Default is 30 seconds.


Security Considerations

1. Controlled by server configuration

Server admins can disable outbound REST access.

2. Least privilege

Use:

• Proxy identities
• Role-based authentication
• Controlled network rules
• Secure key storage

3. Avoid sending sensitive data in plain text

4. Audit outbound requests

Use Extended Events for tracking.


Enterprise Use Cases

1. Real-time data enrichment

Call an external service to enrich data during ETL:

EXEC sys.sp_invoke_external_rest_endpoint
    @method='GET',
    @url='https://api.company.com/geo?ip=198.51.100.4';

2. Send events or logs to cloud monitoring

EXEC sys.sp_invoke_external_rest_endpoint
    @method='POST',
    @url='https://monitoring.company.com/log',
    @payload='{"event":"databaseCheck","status":"ok"}';

3. Machine Learning scoring

EXEC sys.sp_invoke_external_rest_endpoint
    @method='POST',
    @url='https://ml.company.com/score',
    @payload='{"input": [1.2, 3.5, 0.9]}';

4. Trigger an automated workflow

Example using Power Automate or Logic Apps:





EXEC sys.sp_invoke_external_rest_endpoint
    @method='POST',
    @url='https://prod-42.logic.azure.com/workflows/...',
    @payload='{"recordId": 2005}';

5. Push or pull data from microservices

SQL can now participate directly in a service-oriented architecture.


Performance Considerations

This feature should be used responsibly.

Good for

• ETL
• Batch processes
• Scheduled jobs
• Controlled server-to-server calls
• Triggering asynchronous workflows

Not good for

• High-frequency OLTP paths
• Per-row calls
• Inside triggers

Always batch your outbound calls.


Workshop: Hands-On REST Invocation

Step 1. Simple GET

EXEC sys.sp_invoke_external_rest_endpoint
    @method='GET',
    @url='https://api.github.com';

Step 2. POST payload

EXEC sys.sp_invoke_external_rest_endpoint
@method=’POST’,
@url=’https://httpbin.org/post&#8217;,
@payload='{“test”:”Value”}’,
@headers='{“Content-Type”:”application/json”}’;

Step 3. Capture response into a table

DECLARE @response TABLE(JsonText NVARCHAR(MAX));
INSERT INTO @response
EXEC sys.sp_invoke_external_rest_endpoint
    @method='GET',
    @url='https://httpbin.org/get';

SELECT * FROM @response;

Step 4. Parse JSON

DECLARE @auth NVARCHAR(MAX) =
    'Basic ' + BASE64_ENCODE(CONVERT(VARBINARY(200),'user:pass'));

EXEC sys.sp_invoke_external_rest_endpoint
    @method='GET',
    @url='https://httpbin.org/basic-auth/user/pass',
    @headers='{"Authorization":"' + @auth + '"}';

Final Thoughts

SQL Server 2025’s REST invocation feature represents a major shift in how SQL Server participates in modern application architectures. For the first time, SQL can initiate service calls, interact with cloud systems, trigger workflows, and exchange structured JSON with external APIs.

In combination with:

• Native JSON
• JSON indexes
• Base64 functions
• Full RegEx support

SQL Server 2025 becomes far more than a relational engine. It becomes a secure, compliant, cloud-connected integration endpoint capable of orchestrating data flows, analytics, and modern microservice interactions.

This concludes the Advent of 2025 SQL Server Series.


References

• sp_invoke_external_rest_endpoint
https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint

• SQL Server 2025 New Features
https://learn.microsoft.com/sql/sql-server/what-s-new-in-sql-server-2025

• REST and JSON Integration
https://learn.microsoft.com/sql/t-sql/json

• Azure Functions and Logic Apps
https://learn.microsoft.com/azure/logic-apps
https://learn.microsoft.com/azure/azure-functions


Discover more from SQLYARD

Subscribe to get the latest posts sent to your email.

Leave a Reply

Discover more from SQLYARD

Subscribe now to keep reading and get access to the full archive.

Continue reading