agentleFS
apideck-librariesapideck-libraries/api-skills/skills/apideck-dotnet/SKILL.md

apideck-dotnet

Skill4 starsChanged 3 months agoApache-2.0View on GitHub

Apideck Unified API integration patterns for C# and .NET. Use when building integrations with accounting software (QuickBooks, Xero, NetSuite), CRMs (Salesforce, HubSpot, Pipedrive), HRIS platforms (Workday, BambooHR), file storage (Google Drive, Dropbox, Box), ATS systems (Greenhouse, Lever), e-commerce, or any of Apideck's 200+ connectors using .NET. Covers the ApideckUnifySdk NuGet package, authentication, CRUD operations, pagination, error handling, and Vault connection management.

  • Reads credentials

The file

We split this skill into the rules it gives an agent

8 rules. About 0 are common, 1 is distinctive, and 7 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 7

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    ALWAYS use the ApideckUnifySdk NuGet package.

    line 25
  2. Very specific:

    ALWAYS pass apiKey, appId, and consumerId when initializing the client.

    line 26
  3. Very specific:

    USE ServiceId to specify which downstream connector to use (e.g., "salesforce", "quickbooks").

    line 27
  4. Very specific:

    USE async/await for all API calls — all operations return Task<T>.

    line 28
  5. Very specific:

    ALWAYS handle errors with try/catch using BaseException as the base class.

    line 29
  6. Distinctive:

    DO NOT store API keys in source code.

    line 30
  7. Very specific:

    All resources follow the pattern: sdk.{Api}.{Resource}.{Operation}Async(request).

    line 75
  8. Very specific:

    Use the Next method on the response.

    line 131

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Apideck .NET SDK Skill

Overview

The Apideck Unified API provides a single integration layer to connect with 200+ third-party services across accounting, CRM, HRIS, file storage, ATS, e-commerce, and more. The official .NET SDK (ApideckUnifySdk) provides typed clients for all unified APIs.

Installation

dotnet add package ApideckUnifySdk

IMPORTANT RULES

  • ALWAYS use the ApideckUnifySdk NuGet package. DO NOT make raw HttpClient calls to the Apideck API.
  • ALWAYS pass apiKey, appId, and consumerId when initializing the client.
  • USE ServiceId to specify which downstream connector to use (e.g., "salesforce", "quickbooks").
  • USE async/await for all API calls — all operations return Task<T>.
  • ALWAYS handle errors with try/catch using BaseException as the base class.
  • DO NOT store API keys in source code. Use environment variables or a secrets manager.

Quick Start

using ApideckUnifySdk;
using ApideckUnifySdk.Models.Requests;

var sdk = new Apideck(
    consumerId: "your-consumer-id",
    appId: "your-app-id",
    apiKey: Environment.GetEnvironmentVariable("APIDECK_API_KEY") ?? ""
);

var res = await sdk.Crm.Contacts.ListAsync(new CrmContactsAllRequest {
    ServiceId = "salesforce",
    Limit = 20,
});

while (res != null)
{
    foreach (var contact in res.GetContactsResponse?.Data ?? [])
    {
        Console.WriteLine($"{contact.Name} - {contact.Emails?.FirstOrDefault()?.Email}");
    }
    res = await res.Next!();
}

SDK Patterns

Client Setup

using ApideckUnifySdk;

var sdk = new Apideck(
    consumerId: "your-consumer-id",
    appId: "your-app-id",
    apiKey: Environment.GetEnvironmentVariable("APIDECK_API_KEY") ?? ""
);

CRUD Operations

All resources follow the pattern: sdk.{Api}.{Resource}.{Operation}Async(request).

using ApideckUnifySdk;
using ApideckUnifySdk.Models.Requests;
using ApideckUnifySdk.Models.Components;

// LIST
var listRes = await sdk.Crm.Contacts.ListAsync(new CrmContactsAllRequest {
    ServiceId = "salesforce",
    Limit = 20,
    Filter = new ContactsFilter { Email = "john@example.com" },
    Sort = new ContactsSort {
        By = ContactsSortBy.UpdatedAt,
        Direction = SortDirection.Desc,
    },
});

// CREATE
var createRes = await sdk.Crm.Contacts.CreateAsync(new CrmContactsAddRequest {
    ServiceId = "salesforce",
    Contact = new ContactInput {
        FirstName = "John",
        LastName = "Doe",
        Emails = new List<Email> {
            new Email { EmailAddress = "john@example.com", Type = EmailType.Primary },
        },
        PhoneNumbers = new List<PhoneNumber> {
            new PhoneNumber { Number = "+1234567890", Type = PhoneNumberType.Mobile },
        },
    },
});
Console.WriteLine(createRes.CreateContactResponse?.Data?.Id);

// GET
var getRes = await sdk.Crm.Contacts.GetAsync(new CrmContactsOneRequest {
    Id = "contact_123",
    ServiceId = "salesforce",
});

// UPDATE
var updateRes = await sdk.Crm.Contacts.UpdateAsync(new CrmContactsUpdateRequest {
    Id = "contact_123",
    ServiceId = "salesforce",
    Contact = new ContactInput { FirstName = "Jane" },
});

// DELETE
await sdk.Crm.Contacts.DeleteAsync(new CrmContactsDeleteRequest {
    Id = "contact_123",
    ServiceId = "salesforce",
});

Pagination

Use the Next method on the response. Returns null when no more pages:

var res = await sdk.Accounting.Invoices.ListAsync(new AccountingInvoicesAllRequest {
    ServiceId = "quickbooks",
    Limit = 50,
});

while (res != null)
{
    foreach (var invoice in res.GetInvoicesResponse?.Data ?? [])
    {
        Console.WriteLine($"{invoice.Number}: {invoice.Total}");
    }
    res = await res.Next!();
}

Error Handling

using ApideckUnifySdk.Models.Errors;

try
{
    var res = await sdk.Crm.Contacts.GetAsync(new CrmContactsOneRequest { Id = "invalid" });
}
catch (BadRequestResponse e)
{
    Console.Error.WriteLine($"Bad request: {e.Message}");
}
catch (UnauthorizedResponse e)
{
    Console.Error.WriteLine("Invalid API key or missing credentials");
}
catch (NotFoundResponse e)
{
    Console.Error.WriteLine("Record not found");
}
catch (PaymentRequiredResponse e)
{
    Console.Error.WriteLine("API limit reached");
}
catch (UnprocessableResponse e)
{
    Console.Error.WriteLine($"Validation error: {e.Message}");
}
catch (BaseException e)
{
    Console.Error.WriteLine($"API error: {e.Message}");
    Console.Error.WriteLine($"Status: {e.Response.StatusCode}");
}

Retry Configuration

var sdk = new Apideck(
    retryConfig: new RetryConfig(
        strategy: RetryConfig.RetryStrategy.BACKOFF,
        backoff: new BackoffStrategy(
            initialIntervalMs: 1L,
            maxIntervalMs: 50L,
            maxElapsedTimeMs: 100L,
            exponent: 1.1
        ),
        retryConnectionErrors: false
    ),
    consumerId: "your-consumer-id",
    appId: "your-app-id",
    apiKey: Environment.GetEnvironmentVariable("APIDECK_API_KEY") ?? ""
);

API Namespaces

NamespaceResources
sdk.Accounting.*Invoices, Bills, Payments, Customers, Suppliers, LedgerAccounts, JournalEntries, TaxRates, CreditNotes, PurchaseOrders, BalanceSheet, ProfitAndLoss, and more
sdk.Crm.*Contacts, Companies, Leads, Opportunities, Activities, Notes, Pipelines, Users
sdk.Hris.*Employees, Companies, Departments, Payrolls, TimeOffRequests
sdk.FileStorage.*Files, Folders, Drives, DriveGroups, SharedLinks, UploadSessions
sdk.Ats.*Applicants, Applications, Jobs
sdk.Vault.*Connections, Consumers, Sessions, CustomMappings, Logs
sdk.Webhook.*Webhooks, EventLogs

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.