> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://ocient.ferndocs.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://ocient.ferndocs.com/_mcp/server.

# Verify a previous device grant request

POST /v1/sso_device_grant_verify
Content-Type: application/json

Verify a previous device grant request and return an authorization token.

After initiating a device grant flow with /sso\_device\_grant, use this endpoint
to check if the user has completed the verification process. If successful,
it returns an access token that can be used for subsequent API calls.

This endpoint can be called multiple times until either:

* The user completes the verification (returns 200 OK with token)
* The timeout is reached (returns error)
* The verification is cancelled (returns error)

### Example

```bash
curl -X POST https://your-ocient-instance/v1/sso_device_grant_verify \
  -H "Content-Type: application/json" \
  -d '{
    "user_code": "BCDFGHJK",
    "timeout": 60,
    "database": "retail_analytics"
  }'
```

Reference: https://ocient.ferndocs.com/api-reference/sso-integration/ssodevicegrantverify

## Request

### Body (application/json)

This endpoint expects a SSODeviceGrantVerifyRequest.

- `user_code` (string, required) — The user code returned from a previous device grant request. This is the code that was displayed to the user and entered on the verification URI.
- `database` (string, optional) — Target database name (defaults to system if not specified)
- `timeout` (integer, optional, default: 30) — Verification timeout in seconds. This is how long the server will wait for the user to complete the device authorization flow before returning a timeout error. The valid range is 1-600 seconds (10 minutes maximum).

## Response

### 200

Token exchange successful

- `access_token` (string, required) — Access token for subsequent API calls. This token should be included in the Authorization header for all authenticated requests using the format: `Authorization: Bearer {token}`.
- `status` (Status, required) — Status information about the login operation. A successful login will have a SQL state of "00000".
- `username` (string, optional) — The authenticated user's username. This is useful for displaying in UIs or for audit logging purposes.
- `database` (string, optional) — The database that was authenticated against. This is the default database for subsequent queries if none is specified.
- `expires_in` (integer, optional) — Number of seconds until the access token expires. Clients should refresh the token before this time to maintain uninterrupted access.

## Errors

### 401 Unauthorized Error

Unauthorized

- `status` (Status, required)

## Types

### Status

- `reason` (string, required) — Human-readable description of the operation result
- `sql_state` (string, required) — SQL state code (see Error Handling section for common codes)
- `vendor_code` (integer, required) — Vendor-specific error code

## Examples

### Successful Device Verification Response

**Response**

```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqZG9lIiwiZGIiOiJyZXRhaWxfYW5hbHl0aWNzIiwiZXhwIjoxNjM1NDYxNzEyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "status": {
    "reason": "Authentication successful",
    "sql_state": "00000",
    "vendor_code": 0
  },
  "username": "jdoe",
  "database": "retail_analytics"
}
```

**SDK Code**

```python Successful Device Verification Response
import requests

url = "https://v1/sso_device_grant_verify"

response = requests.post(url)

print(response.json())
```

```javascript Successful Device Verification Response
const url = 'https://v1/sso_device_grant_verify';
const options = {method: 'POST'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Successful Device Verification Response
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://v1/sso_device_grant_verify"

	req, _ := http.NewRequest("POST", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Successful Device Verification Response
require 'uri'
require 'net/http'

url = URI("https://v1/sso_device_grant_verify")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)

response = http.request(request)
puts response.read_body
```

```java Successful Device Verification Response
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://v1/sso_device_grant_verify")
  .asString();
```

```php Successful Device Verification Response
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://v1/sso_device_grant_verify');

echo $response->getBody();
```

```csharp Successful Device Verification Response
using RestSharp;

var client = new RestClient("https://v1/sso_device_grant_verify");
var request = new RestRequest(Method.POST);
IRestResponse response = client.Execute(request);
```

```swift Successful Device Verification Response
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://v1/sso_device_grant_verify")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

### Device Grant Verification Request

**Request**

```json
{
  "user_code": "BCDFGHJK",
  "database": "retail_analytics",
  "timeout": 60
}
```

**Response**

```json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJqZG9lIiwiZGIiOiJyZXRhaWxfYW5hbHl0aWNzIiwiZXhwIjoxNjM1NDYxNzEyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c",
  "status": {
    "reason": "Authentication successful",
    "sql_state": "00000",
    "vendor_code": 0
  },
  "username": "jdoe",
  "database": "retail_analytics"
}
```

**SDK Code**

```python Device Grant Verification Request
import requests

url = "https://v1/sso_device_grant_verify"

payload = {
    "user_code": "BCDFGHJK",
    "database": "retail_analytics",
    "timeout": 60
}
headers = {"Content-Type": "application/json"}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript Device Grant Verification Request
const url = 'https://v1/sso_device_grant_verify';
const options = {
  method: 'POST',
  headers: {'Content-Type': 'application/json'},
  body: '{"user_code":"BCDFGHJK","database":"retail_analytics","timeout":60}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Device Grant Verification Request
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://v1/sso_device_grant_verify"

	payload := strings.NewReader("{\n  \"user_code\": \"BCDFGHJK\",\n  \"database\": \"retail_analytics\",\n  \"timeout\": 60\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Device Grant Verification Request
require 'uri'
require 'net/http'

url = URI("https://v1/sso_device_grant_verify")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n  \"user_code\": \"BCDFGHJK\",\n  \"database\": \"retail_analytics\",\n  \"timeout\": 60\n}"

response = http.request(request)
puts response.read_body
```

```java Device Grant Verification Request
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://v1/sso_device_grant_verify")
  .header("Content-Type", "application/json")
  .body("{\n  \"user_code\": \"BCDFGHJK\",\n  \"database\": \"retail_analytics\",\n  \"timeout\": 60\n}")
  .asString();
```

```php Device Grant Verification Request
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://v1/sso_device_grant_verify', [
  'body' => '{
  "user_code": "BCDFGHJK",
  "database": "retail_analytics",
  "timeout": 60
}',
  'headers' => [
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Device Grant Verification Request
using RestSharp;

var client = new RestClient("https://v1/sso_device_grant_verify");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"user_code\": \"BCDFGHJK\",\n  \"database\": \"retail_analytics\",\n  \"timeout\": 60\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Device Grant Verification Request
import Foundation

let headers = ["Content-Type": "application/json"]
let parameters = [
  "user_code": "BCDFGHJK",
  "database": "retail_analytics",
  "timeout": 60
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://v1/sso_device_grant_verify")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```