# getTestClock

getTestClock returns the current frozen time, posted and pending synthetic transactions, and each goal's progress with its posted and upcoming contributions. C…

Last updated October 2, 2026

## Reference

Authentication: **bearer token required** (see [how to get a token](https://financesavi.com/developers/authentication#get-a-token))

```
getTestClock returns the current frozen time, posted and pending synthetic transactions, and each goal's progress with its posted and upcoming contributions. Clocks are visible only to their creator and expire automatically.
```

## getTestClock request

POST https://api-v2.financesavi.com/rpc · Bearer token required

### cURL

```bash
curl -sS --max-time 30 -X POST 'https://api-v2.financesavi.com/rpc' \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $SAVI_TOKEN" \
  -d '{"jsonrpc":"2.0","method":"getTestClock","params":{"id":"tc_example"},"id":1}'
```

### JavaScript

```javascript
const response = await fetch("https://api-v2.financesavi.com/rpc", {
  method: 'POST',
  signal: AbortSignal.timeout(30_000),
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.SAVI_TOKEN}`,
  },
  body: JSON.stringify({
      "jsonrpc": "2.0",
      "method": "getTestClock",
      "params": {
        "id": "tc_example"
      },
      "id": 1
    }),
});
console.log(await response.json());
```

### TypeScript

```typescript
const response = await fetch("https://api-v2.financesavi.com/rpc", {
  method: 'POST',
  signal: AbortSignal.timeout(30_000),
  headers: {
    'Content-Type': 'application/json',
    Authorization: `Bearer ${process.env.SAVI_TOKEN}`,
  },
  body: JSON.stringify({
      "jsonrpc": "2.0",
      "method": "getTestClock",
      "params": {
        "id": "tc_example"
      },
      "id": 1
    }),
});
console.log(await response.json());
```

### Python

```python
import os
import requests

response = requests.post(
    "https://api-v2.financesavi.com/rpc",
    headers={"Authorization": f"Bearer {os.environ['SAVI_TOKEN']}"},
    json={
        "jsonrpc": "2.0",
        "method": "getTestClock",
        "params": {
            "id": "tc_example",
        },
        "id": 1,
    },
    timeout=30,
)
print(response.json())
```

### Go

```go
package main

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

func main() {
  payload := strings.NewReader("{\"jsonrpc\":\"2.0\",\"method\":\"getTestClock\",\"params\":{\"id\":\"tc_example\"},\"id\":1}")
  req, err := http.NewRequest("POST", "https://api-v2.financesavi.com/rpc", payload)
  if err != nil { panic(err) }
  req.Header.Set("Content-Type", "application/json")
  req.Header.Set("Authorization", "Bearer " + os.Getenv("SAVI_TOKEN"))
  client := &http.Client{Timeout: 30 * time.Second}
  res, err := client.Do(req)
  if err != nil { panic(err) }
  defer res.Body.Close()
  body, err := io.ReadAll(res.Body)
  if err != nil { panic(err) }
  fmt.Println(res.Status, string(body))
}
```

### C#

```csharp
// .NET 6 or later
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Environment.GetEnvironmentVariable("SAVI_TOKEN"));
using var content = new StringContent(@"{""jsonrpc"":""2.0"",""method"":""getTestClock"",""params"":{""id"":""tc_example""},""id"":1}", Encoding.UTF8, "application/json");
using var response = await client.PostAsync(@"https://api-v2.financesavi.com/rpc", content);
Console.WriteLine($"HTTP {(int)response.StatusCode}");
Console.WriteLine(await response.Content.ReadAsStringAsync());
```

### Java

```java
// Java 11+: save as SaviExample.java, then run java SaviExample.java
import java.net.URI;
import java.net.http.*;
import java.time.Duration;

class SaviExample {
  public static void main(String[] args) throws Exception {
    var client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(30)).build();
    var builder = HttpRequest.newBuilder(URI.create("https://api-v2.financesavi.com/rpc"))
        .timeout(Duration.ofSeconds(30))
        .header("Content-Type", "application/json");
    builder.header("Authorization", "Bearer " + System.getenv("SAVI_TOKEN"));
    var request = builder.POST(HttpRequest.BodyPublishers.ofString("{\"jsonrpc\":\"2.0\",\"method\":\"getTestClock\",\"params\":{\"id\":\"tc_example\"},\"id\":1}")).build();
    var response = client.send(request, HttpResponse.BodyHandlers.ofString());
    System.out.println("HTTP " + response.statusCode());
    System.out.println(response.body());
  }
}
```

### PHP

```php
<?php
// Requires the PHP cURL extension.
$curl = curl_init('https://api-v2.financesavi.com/rpc');
curl_setopt_array($curl, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CONNECTTIMEOUT => 30,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/json',
        'Authorization: Bearer ' . getenv('SAVI_TOKEN'),
    ],
    CURLOPT_POSTFIELDS => '{"jsonrpc":"2.0","method":"getTestClock","params":{"id":"tc_example"},"id":1}',
]);
$body = curl_exec($curl);
if ($body === false) {
    throw new RuntimeException(curl_error($curl));
}
echo "HTTP " . curl_getinfo($curl, CURLINFO_HTTP_CODE) . PHP_EOL;
echo $body . PHP_EOL;
curl_close($curl);
```

### Ruby

```ruby
require 'net/http'
require 'uri'

uri = URI('https://api-v2.financesavi.com/rpc')
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request['Authorization'] = 'Bearer ' + ENV.fetch('SAVI_TOKEN')
request.body = '{"jsonrpc":"2.0","method":"getTestClock","params":{"id":"tc_example"},"id":1}'
response = Net::HTTP.start(uri.host, uri.port,
  use_ssl: uri.scheme == 'https', open_timeout: 30, read_timeout: 30, write_timeout: 30
) { |http| http.request(request) }
puts "HTTP #{response.code}"
puts response.body
```

### Swift

```swift
// Swift 5.5+: save as SaviExample.swift, then run swift SaviExample.swift
import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

var request = URLRequest(url: URL(string: "https://api-v2.financesavi.com/rpc")!)
request.httpMethod = "POST"
request.timeoutInterval = 30
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
guard let token = ProcessInfo.processInfo.environment["SAVI_TOKEN"] else { fatalError("Set SAVI_TOKEN first") }
request.setValue("Bearer " + token, forHTTPHeaderField: "Authorization")
request.httpBody = Data("{\"jsonrpc\":\"2.0\",\"method\":\"getTestClock\",\"params\":{\"id\":\"tc_example\"},\"id\":1}".utf8)
let configuration = URLSessionConfiguration.ephemeral
configuration.timeoutIntervalForResource = 30
let session = URLSession(configuration: configuration)
let (data, response) = try await session.data(for: request)
if let http = response as? HTTPURLResponse { print("HTTP", http.statusCode) }
print(String(decoding: data, as: UTF8.self))
```

### Local API capture (scrubbed) (HTTP 200)

```json
{
  "jsonrpc": "2.0",
  "result": {
    "clock": {
      "id": "tc_example",
      "status": "READY",
      "frozenTime": "2026-10-02T19:24:43.985Z",
      "maxTime": "2036-10-02T18:24:43.985Z",
      "expiresAt": "2026-10-09T18:25:43.99Z",
      "transactions": [
        {
          "id": "txn_001",
          "at": "2026-10-02T19:24:43.985Z",
          "name": "Simulated payroll",
          "amount": 2500,
          "currency": "CAD",
          "type": "INCOME",
          "source": "SIMULATED_TEST_CLOCK"
        }
      ],
      "pendingTransactions": [],
      "goals": [
        {
          "id": "goal_001",
          "name": "Emergency fund",
          "targetAmount": 1000,
          "currentAmount": 250,
          "remainingAmount": 750,
          "progressPercent": 25,
          "contributions": [
            {
              "id": "contribution_001",
              "at": "2026-10-02T19:24:43.985Z",
              "amount": 150
            }
          ],
          "upcomingContributions": [
            {
              "id": "contribution_002",
              "at": "2026-10-02T20:24:43.985Z",
              "amount": 250
            }
          ]
        }
      ]
    }
  },
  "id": 1
}
```

Source: https://financesavi.com/developers/api/getTestClock
