Skip to main content

Using the SDK

If you’re using the @usenotra/sdk package, types are already included. Import them directly:
import type {
  GetPostPost,
  ListPostsPost,
  Pagination,
} from "@usenotra/sdk/models/operations";
The SDK ships with full type definitions — no need to maintain your own. The types below are only needed if you’re calling the API with raw fetch.

Using fetch

If you call the API directly with fetch, these types are a good starting point:
// Multiple posts
const listResponse = await fetch("https://api.usenotra.com/v1/posts", {
  headers: { Authorization: `Bearer ${process.env.NOTRA_API_KEY}` },
});
const listData: NotraPostListResponse = await listResponse.json();

// Single post
const postResponse = await fetch(
  "https://api.usenotra.com/v1/posts/YOUR_POST_ID",
  {
    headers: { Authorization: `Bearer ${process.env.NOTRA_API_KEY}` },
  }
);
const postData: NotraPostResponse = await postResponse.json();

// Updated post
const updateResponse = await fetch(
  "https://api.usenotra.com/v1/posts/YOUR_POST_ID",
  {
    method: "PATCH",
    headers: {
      "Content-Type": "application/json",
      Authorization: `Bearer ${process.env.NOTRA_API_KEY}`,
    },
    body: JSON.stringify({
      title: "Ship notes for week 11",
      markdown: "# Ship notes\n\nWe shipped a faster editor.",
      status: "published",
    }),
  }
);
const updateData: NotraPostUpdateResponse = await updateResponse.json();

Type Definitions

Copy these types into your project:
export type SourceMetadata = {
  triggerId: string;
  repositories: Array<{
    owner: string;
    repo: string;
  }>;
  lookbackRange: {
    start: string; // ISO datetime
    end: string; // ISO datetime
  };
  lookbackWindow: string;
  triggerSourceType: string;
};

export type Post = {
  id: string;
  title: string;
  content: string; // HTML string
  markdown: string;
  recommendations: string | null;
  contentType: string;
  sourceMetadata: SourceMetadata | null;
  status: "draft" | "published";
  createdAt: string;
  updatedAt: string;
};

export type Pagination = {
  limit: number;
  currentPage: number;
  nextPage: number | null;
  previousPage: number | null;
  totalItems: number;
  totalPages: number;
};

export type NotraPostListResponse = {
  posts: Post[];
  pagination: Pagination;
};

export type NotraPostResponse = {
  post: Post | null;
};

export type Organization = {
  id: string;
  slug: string;
  name: string;
  logo: string | null;
};

export type NotraPostUpdateRequest = {
  title?: string;
  markdown?: string;
  status?: "draft" | "published";
};

export type NotraPostUpdateResponse = {
  organization: Organization;
  post: Post;
};
Copy these type definitions into a types/notra.ts file in your project.

Zod Schemas

For runtime validation, you can use these Zod schemas:
import * as z from "zod";

export const SourceMetadataSchema = z.object({
  triggerId: z.string(),
  repositories: z.array(
    z.object({
      owner: z.string(),
      repo: z.string(),
    })
  ),
  lookbackRange: z.object({
    start: z.string().datetime(),
    end: z.string().datetime(),
  }),
  lookbackWindow: z.string(),
  triggerSourceType: z.string(),
});

export const PostSchema = z.object({
  id: z.string(),
  title: z.string(),
  content: z.string(), // HTML string
  markdown: z.string(),
  recommendations: z.string().nullable(),
  contentType: z.string(),
  sourceMetadata: SourceMetadataSchema.nullable(),
  status: z.enum(["draft", "published"]),
  createdAt: z.string().datetime(),
  updatedAt: z.string().datetime(),
});

export const PaginationSchema = z.object({
  limit: z.number(),
  currentPage: z.number(),
  nextPage: z.number().nullable(),
  previousPage: z.number().nullable(),
  totalItems: z.number(),
  totalPages: z.number(),
});

export const PostListResponseSchema = z.object({
  posts: z.array(PostSchema),
  pagination: PaginationSchema,
});

export const PostResponseSchema = z.object({
  post: PostSchema.nullable(),
});

export const OrganizationSchema = z.object({
  id: z.string(),
  slug: z.string(),
  name: z.string(),
  logo: z.string().nullable(),
});

export const PostUpdateRequestSchema = z.object({
  title: z.string().min(1).max(120).optional(),
  markdown: z.string().min(1).optional(),
  status: z.enum(["draft", "published"]).optional(),
});

export const PostUpdateResponseSchema = z.object({
  organization: OrganizationSchema,
  post: PostSchema,
});