Skip to content

Zod Schemas

The SDK includes Zod schemas for all request bodies, enabling form validation that matches the API exactly.

Importing Schemas

Import Zod Schemastypescript
import { zod } from "@spaceinvoices/js-sdk";

// Access schemas by resource (PascalCase naming)
const _invoiceSchema = zod.invoices.CreateInvoiceBody;
const _customerSchema = zod.customers.CreateCustomerBody;
const _itemSchema = zod.items.CreateItemBody;

Available Schemas

Schemas are organized by resource:

ImportContains
zod.invoicesInvoice creation/update schemas
zod.customersCustomer schemas
zod.itemsItem/product schemas
zod.paymentsPayment schemas
zod.entitiesEntity schemas
zod.taxesTax rate schemas

Form Validation

Use schemas with safeParse for form validation:

Form Validationtypescript
import { zod } from "@spaceinvoices/js-sdk";

const formData = {
  date: "2024-01-15",
  items: [{ name: "Service", price: 100 }],
};

const result = zod.invoices.CreateInvoiceBody.safeParse(formData);

if (!result.success) {
  // Handle validation errors
  result.error.issues.forEach((_issue) => {});
} else {
  // Data is valid
  const validData = result.data;
  await sdk.invoices.create(validData);
}

With React Hook Form

Integrate with react-hook-form using @hookform/resolvers:

React Hook Formtypescript
import { zodResolver } from "@hookform/resolvers/zod";
import { zod } from "@spaceinvoices/js-sdk";
import { useForm } from "react-hook-form";
import type { z } from "zod";

type InvoiceFormData = z.infer;

function _CreateInvoiceForm() {
  const form = useForm({
    resolver: zodResolver(zod.invoices.CreateInvoiceBody),
    defaultValues: {
      date: new Date().toISOString().split("T")[0],
      items: [{ name: "", price: 0 }],
    },
  });

  const onSubmit = async (data: InvoiceFormData) => {
    await sdk.invoices.create({ entityId: "ent_123", body: data });
  };

  return 
handleSubmit(onSubmit)}>{/* Form fields */}
; }

Schema Structure

Each resource has schemas for different operations. Schema names use PascalCase:

// Invoice schemas
zod.invoices.CreateInvoiceBody // For creating invoices
zod.invoices.UpdateInvoiceBody // For updating invoices
// Customer schemas
zod.customers.CreateCustomerBody
zod.customers.UpdateCustomerBody
// Item schemas
zod.items.CreateItemBody
zod.items.UpdateItemBody

Type Inference

Extract TypeScript types from schemas:

Type Inferencetypescript
import type { zod } from "@spaceinvoices/js-sdk";
import type { z } from "zod";

// Infer types from schemas
type CreateInvoiceBody = z.infer;
type CreateCustomerBody = z.infer;
type InvoiceItem = z.infer["items"][number];

// Use in your code
const _invoice: CreateInvoiceBody = {
  date: "2024-01-15",
  items: [{ name: "Service", price: 100 }],
};

Partial Schemas

For partial updates, use Zod’s .partial():

Partial Updatestypescript
import { zod } from "@spaceinvoices/js-sdk";

// Make all fields optional for partial updates
const partialCustomerSchema = zod.customers.CreateCustomerBody.partial();

// Validate partial data
const result = partialCustomerSchema.safeParse({
  email: "new-email@example.com",
});

if (result.success) {
  await sdk.customers.update("cust_123", result.data);
}

Best Practices

  1. Validate before submit — Use safeParse to validate form data before API calls
  2. Display errors — Map Zod issues to form field errors
  3. Type safety — Use inferred types for form state
  4. Server validation — The API validates too; client validation improves UX

Next Steps