> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.xbox.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart (Windows) - Calling PlayFab Services

> Use the authenticated PFEntityHandle from the PlayFab Unified SDK to retrieve entity keys and call PlayFab service APIs from a Windows title.

This guide shows you how to make PlayFab service API calls using the unified SDK. You'll learn how to call various PlayFab services to manage player data, retrieve files, and interact with other PlayFab features.

## Prerequisites

Before you begin, ensure you have:

* Completed the [core SDK setup and authentication](/services/playfab/sdks/unified-sdk/quickstart-core)
* An authenticated `PFEntityHandle` from the login process
* Your PlayFab Title ID and service configuration set up

<Note>
  This guide assumes you've already initialized the PlayFab SDK and authenticated a player following the [core quickstart guide](/services/playfab/sdks/unified-sdk/quickstart-core). If you haven't done so, please complete that guide first.
</Note>

## What you'll accomplish

By the end of this quickstart, you'll have:

* Retrieved the entity key for an authenticated player
* Made your first PlayFab service API call
* Processed the response from a PlayFab service

## Making your first service API call

After successful authentication, you can make PlayFab API calls using the `PFEntityHandle` obtained during login. This example shows how to retrieve files stored for the current player.

### Step 1: Get the Entity Key

First, retrieve the entity key from your authenticated entity handle:

```cpp theme={null}
PFEntityKey const* pEntityKey{};
std::vector<char> entityKeyBuffer;
size_t size{};
HRESULT hr = PFEntityGetEntityKeySize(entityHandle, &size);
if (FAILED(hr))
{
    std::wcerr << L"Failed to get entity key size: 0x" << std::hex << hr << std::endl;
    return hr;
}

entityKeyBuffer.resize(size);
hr = PFEntityGetEntityKey(entityHandle, entityKeyBuffer.size(), 
    entityKeyBuffer.data(), &pEntityKey, nullptr);
if (FAILED(hr))
{
    std::wcerr << L"Failed to get entity key: 0x" << std::hex << hr << std::endl;
    return hr;
}

std::wcout << L"Entity ID: " << pEntityKey->id << std::endl;
```

### Step 2: Call the GetFiles API

Now make your first PlayFab service call to get files associated with the player:

```cpp theme={null}
// Prepare the request
XAsyncBlock async{};
PFDataGetFilesRequest requestFiles{};
requestFiles.entity = pEntityKey;  // Use the entity key from above

// Make the async API call
HRESULT hr = PFDataGetFilesAsync(entityHandle, &requestFiles, &async);
if (FAILED(hr))
{
    std::wcerr << L"Failed to start GetFiles request: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Wait for the call to complete
hr = XAsyncGetStatus(&async, true);
if (FAILED(hr))
{
    std::wcerr << L"GetFiles request failed: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Get the result size and allocate buffer
size_t resultSize;
hr = PFDataGetFilesGetResultSize(&async, &resultSize);
if (FAILED(hr))
{
    std::wcerr << L"Failed to get result size: 0x" << std::hex << hr << std::endl;
    return hr;
}

// Retrieve the actual result
std::vector<char> getFilesResultBuffer(resultSize);
PFDataGetFilesResponse* getFilesResponseResult{ nullptr };
hr = PFDataGetFilesGetResult(&async, getFilesResultBuffer.size(), 
    getFilesResultBuffer.data(), &getFilesResponseResult, nullptr);
if (SUCCEEDED(hr))
{
    std::wcout << L"Successfully retrieved files. Count: " 
               << (getFilesResponseResult->metadata ? getFilesResponseResult->metadataCount : 0) 
               << std::endl;
    
    // Process the files as needed
    if (getFilesResponseResult->metadata)
    {
        for (uint32_t i = 0; i < getFilesResponseResult->metadataCount; ++i)
        {
            std::wcout << L"File: " << getFilesResponseResult->metadata[i].fileName << std::endl;
        }
    }
}
else
{
    std::wcerr << L"Failed to get GetFiles result: 0x" << std::hex << hr << std::endl;
}
```

🎉 **Congratulations!** You've successfully made your first PlayFab service API call using the Unified SDK.

## Understanding the API call pattern

All PlayFab service API calls follow a similar pattern:

1. **Prepare the request** - Create and populate a request structure
2. **Initiate the async call** - Call the `*Async` function
3. **Wait for completion** - Use `XAsyncGetStatus` to wait for the operation
4. **Get result size** - Call `*GetResultSize` to determine buffer needs
5. **Retrieve the result** - Call `*GetResult` to get the actual data

This pattern applies to all PlayFab service APIs, making it easy to work with different services once you understand the basics.

## Next steps

Now that you've successfully called a PlayFab service, explore these additional features:

### Common service APIs

* **Player Data Management** - Store and retrieve custom player data
* **Player Statistics** - Track player stats and achievements
* **Title Data** - Access game configuration data
* **Cloud Script** - Execute server-side logic

### Advanced features

* **Leaderboards** - Implement competitive features with rankings
* **Economy and Monetization** - Add virtual currencies and items
* **Multiplayer** - Integrate matchmaking and lobby services
* **Analytics** - Track player behavior and game metrics

### Best practices

* [Asynchronous operations](/services/playfab/sdks/unified-sdk/async-model) - Understanding PlayFab's async programming model
* [Memory management](/services/playfab/sdks/unified-sdk/memory-management) - Best practices for managing SDK memory
* [Tracing and diagnostics](/services/playfab/sdks/unified-sdk/debug-trace) - Debugging and monitoring your integration

## Troubleshooting

**Common issues and solutions:**

| Issue                 | Solution                                              |
| --------------------- | ----------------------------------------------------- |
| Invalid entity handle | Ensure you completed authentication successfully      |
| API call timeout      | Check network connectivity and PlayFab service status |
| Access denied errors  | Verify your Title ID and entity permissions           |
| Buffer size errors    | Always call `*GetResultSize` before `*GetResult`      |

For more detailed error information, enable [tracing and diagnostics](/services/playfab/sdks/unified-sdk/debug-trace) in your application.

## Reference documentation

* [PlayFab Unified SDK API Reference](/services/playfab/api-references/c/pfauthentication/pfauthentication_members)
* [PlayFab Services API Reference](/services/playfab/api-references)
* [PlayFab Data API Documentation](https://docs.microsoft.com/gaming/playfab/api-references/data/)


## Related topics

- [Unreal Engine quickstart](/services/playfab/sdks/unreal/quickstart.md)
- [PlayFab CloudScript using Azure Functions Quickstart Guide](/services/playfab/live-service-management/service-gateway/automation/cloudscript-af/quickstart.md)
- [Quickstart](/services/playfab/economy-monetization/economy-v2/quickstart.md)
- [Quickstart (Windows) - Core SDK Setup](/services/playfab/sdks/unified-sdk/quickstart-core.md)
- [Quickstart C++ for Windows](/services/playfab/sdks/playfab-cpp/quickstart-windows.md)
