# Organization schema and logo implementation kit

Describe the company separately from its software, connect the website to its publisher, and check the actual logo file referenced by the markup. A working homepage does not prove that its image exists or meets the intended requirements. This fictional example pairs a complete company graph with a runnable HTTP lab: the homepage succeeds in all three cases, while an undersized logo and a missing file fail separate asset checks.

Pack version 1.0 · 17 September 2026. Original examples and external observations: 12 September 2026.

Guide: https://rankecho.io/resources/fix/organization-schema

Download [the complete ZIP kit](https://rankecho.io/downloads/organization-schema-kit-v1.zip).

## Open the kit

Extract all files into a local folder. Start with GUIDE.md for the editable field map, validation records, complete article and FAQ. `example.html` is the exact original teaching HTML. Open it in a text editor to inspect visible content and JSON-LD together. The organization and product HTML reference reserved image URLs; a local preview may show a missing image. Those URLs and the fictional purchase links are placeholders, not working production services.

`source-fixture.json` and `historical-observations.json` preserve the original inputs and dated observations. `SHA256SUMS.txt` records the kit's original bytes; preserve a clean copy before editing. The HTML templates themselves do not require a runtime. External validators and production URL checks remain separate work.

## Run the logo lab

Use Node 24 with its standard library; no packages are needed. Open a terminal in the extracted folder and run:

```sh
node organization-example.mjs
node organization-example.mjs --html > homepage.html
```

The first command temporarily starts a server on loopback, tests ready, undersized and missing logo responses, prints JSON and closes the server. It makes no external requests. Compare its three results with `expected-logo-results.json`. The second command prints the exact example.com homepage HTML; its generated `homepage.html` ends with the normal console newline, while `example.html` preserves the original stored string bytes.

The ready fixture passes status, SVG MIME and explicit-dimension checks; the 96-pixel and 404 fixtures fail. This is a fixed-fixture demonstration, not a general schema validator, image decoder, production crawler or Google approval. Inspect a real logo's appearance and actual host access separately.

## Prepare a real release

Keep syntax/vocabulary, visible-page relevance, feature requirements and deployed behavior as separate decisions. Preserve failed or unavailable checks with an owner and next action. Do not invent ratings, legal identity, product facts, prices or access results to make a test appear complete. Preview RankEcho's reviewed page-change workflow at https://rankecho.io/sample-fix and https://rankecho.io/product/fix-engine; external validation and shipment remain explicit operator work.

## Your implementation record

- **Target page URL:** [Enter your response]
- **Intended entity type and stable identifier:** [Enter your response]
- **Current emitter and version:** [Enter your response]
- **Proposed emitter or bounded change:** [Enter your response]
- **Approved facts and source record:** [Enter your response]
- **Page owner:** [Enter your response]
- **Implementer:** [Enter your response]
- **Review date:** [Enter your response]
- **Before version and rollback location:** [Enter your response]
- **Approved common name, legal name and operator:** [Enter your response]
- **WebSite identifier and publisher reference:** [Enter your response]
- **Published logo URL and asset owner:** [Enter your response]
- **Logo response, format, dimensions, white-background appearance and crawl access:** [Enter your response]

## Field and evidence map

Repeat the row for each proposed property. Record an inspected source and responsible owner; an example value is not evidence for your page.

| Property | Proposed value | Visible page evidence | Approved source and date | Emitter | Owner |
| --- | --- | --- | --- | --- | --- |
| [property] | [value] | [section or capture] | [source and approval] | [template or plugin] | [owner] |

## Validation records

| Check | Exact input and date | Actual result or unavailable reason | Owner and next action |
| --- | --- | --- | --- |
| JSON syntax and extracted graph | [input/version/date] | [result] | [owner/action] |
| Schema.org vocabulary | [input/mode/date] | [result] | [owner/action] |
| Visible content and entity relevance | [page/capture/date] | [result] | [owner/action] |
| Applicable search-feature requirements | [feature/source/date] | [result] | [owner/action] |
| Google feature test where supported | [input/mode/date] | [result or unavailable] | [owner/action] |
| Deployed page, assets and purchase path where relevant | [URLs/captures/date] | [result or pending] | [owner/action] |

## Release decision

- **Unresolved checks and accountable owner:** [Enter your response]
- **Review decision and approver:** [Enter your response]
- **Approved diff and rollback trigger:** [Enter your response]
- **Deployed verification record and date:** [Enter your response]

## Copy the company homepage and logo lab

Save as organization-example.mjs and run node organization-example.mjs with Node 24. No packages are needed. Run node organization-example.mjs --html > homepage.html to inspect the complete fictional HTML. The lab uses loopback HTTP and closes its server when finished.

```javascript
// Fictional local HTTP lab. Node 24; no packages or external requests.
import { createServer } from 'node:http';
import assert from 'node:assert/strict';

export function homepage(origin, variant = 'ready') {
  const logo = `${origin}/logo.svg?variant=${variant}`;
  const graph = {
    '@context': 'https://schema.org',
    '@graph': [
      {
        '@type': 'Organization',
        '@id': `${origin}/#organization`,
        name: 'Cedar Quay',
        legalName: 'Cedar Quay Software LLC',
        url: `${origin}/`,
        description: 'A fictional company making bookkeeping software.',
        logo,
      },
      {
        '@type': 'WebSite',
        '@id': `${origin}/#website`,
        url: `${origin}/`,
        name: 'Cedar Quay',
        publisher: { '@id': `${origin}/#organization` },
      },
    ],
  };
  return `<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Cedar Quay — fictional company example</title>
<link rel="canonical" href="${origin}/">
<script type="application/ld+json">
${JSON.stringify(graph, null, 2)}
</script>
</head>
<body>
<main>
<img src="${logo}" alt="Cedar Quay logo">
<h1>Cedar Quay</h1>
<p>A fictional company making bookkeeping software.</p>
<p>Cedar Quay Software LLC operates this website.</p>
<p>This is a teaching example, not a real company.</p>
</main>
</body>
</html>`;
}

function logoSvg(size) {
  return `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 256 256"><rect width="256" height="256" fill="white"/><path d="M176 64H96L64 96v64l32 32h80v-32h-64l-16-16v-32l16-16h64z" fill="#17324d"/></svg>`;
}

async function runLab() {
  let origin;
  const server = createServer((request, response) => {
    const url = new URL(request.url, origin);
    const variant = url.searchParams.get('variant') || 'ready';
    if (url.pathname === '/') {
      response.writeHead(200, { 'content-type': 'text/html; charset=utf-8' });
      return response.end(homepage(origin, variant));
    }
    if (url.pathname === '/logo.svg' && variant !== 'missing') {
      response.writeHead(200, { 'content-type': 'image/svg+xml' });
      return response.end(logoSvg(variant === 'small' ? 96 : 256));
    }
    response.writeHead(404, { 'content-type': 'text/plain' });
    response.end('Not found');
  });
  await new Promise(resolve => server.listen(0, '127.0.0.1', resolve));
  origin = `http://127.0.0.1:${server.address().port}`;
  const results = [];
  try {
    for (const variant of ['ready', 'small', 'missing']) {
      const page = await fetch(`${origin}/?variant=${variant}`);
      const html = await page.text();
      // Fixed-shape fixture extraction, not a general HTML/JSON-LD parser.
      const block = html.match(/<script type="application\/ld\+json">\n([\s\S]*?)\n<\/script>/);
      const graph = JSON.parse(block[1])['@graph'];
      const company = graph.find(node => node['@type'] === 'Organization');
      const site = graph.find(node => node['@type'] === 'WebSite');
      const asset = await fetch(company.logo);
      const svg = await asset.text();
      // These fixtures use explicit integer SVG dimensions. This is not an image decoder.
      const dimensions = svg.match(/<svg[^>]* width="(\d+)" height="(\d+)"/);
      const width = dimensions ? Number(dimensions[1]) : null;
      const height = dimensions ? Number(dimensions[2]) : null;
      const result = {
        variant,
        homepageStatus: page.status,
        graphTypes: graph.map(node => node['@type']),
        publisherMatches: site.publisher['@id'] === company['@id'],
        logoStatus: asset.status,
        logoContentType: asset.headers.get('content-type'),
        width,
        height,
        logoChecksPass: asset.ok && asset.headers.get('content-type') === 'image/svg+xml'
          && width >= 112 && height >= 112,
      };
      assert.equal(result.homepageStatus, 200);
      assert.equal(result.publisherMatches, true);
      assert.equal(result.logoStatus, variant === 'missing' ? 404 : 200);
      assert.equal(result.logoChecksPass, variant === 'ready');
      results.push(result);
    }
    console.log(JSON.stringify(results, null, 2));
  } finally {
    await new Promise(resolve => server.close(resolve));
  }
}

if (process.argv.includes('--html')) {
  console.log(homepage('https://example.com'));
} else {
  await runLab();
}

```

Cedar Quay and its logo are fictional. Replace example.com, company facts and the test logo URLs before adapting the HTML. This fixed-fixture lab is not a production crawler or general schema validator.

## What belongs in the company homepage graph?

Start with approved company facts and one intended publishing relationship. Cedar Quay is the common name; Cedar Quay Software LLC is the fictional legal name. The website has its own identifier and references the company's identifier through publisher. The software application is a separate entity and is deliberately absent from this company-only example.

Google recommends organization markup on the homepage or one page describing the organization, and the most specific applicable subtype. It sets no required organization properties. Our minimal teaching company uses the broad Organization type; review a real business against more specific types before implementation. A SaaS label alone does not establish a physical local-business location.

For a site-name preference, Google expects WebSite markup on the domain or subdomain homepage, with name and url. Extend an existing WebSite node where appropriate. Organization and WebSite serve different descriptive roles even when their names and URLs match. Google's chosen site name is still automatic.

- [Review organization placement and types](https://developers.google.com/search/docs/appearance/structured-data/organization)
- [Check homepage site-name guidance](https://developers.google.com/search/docs/appearance/site-names)
- [Implement the separate software application](https://rankecho.io/resources/fix/softwareapplication-schema)

## How do you prepare the fields and emitter?

Record the intended homepage, company ID, website ID, field owner and template or plugin that will emit the graph. The two fragment identifiers in the copied example are stable references to different things. Reusing one identifier for both would erase the distinction the publishing relationship is meant to express.

The example repeats the company name, description and operator in visible HTML, and uses the same logo URL in the image element and JSON-LD. It omits unverified addresses, social accounts, tax identifiers and contact details. For a real sameAs value, Google's guidance calls for another page about the same organization; a founder's profile or a related product is a different entity.

Inspect existing emitters before adding this graph. If company identity is already contradictory, resolve that conflict with the identity guide. If a theme or plugin emits stale values, trace the field to that source with the mismatch guide. The copied snippet is a starting implementation, not a reason to stack competing snippets.

| Record | Fictional implementation | Release check |
| --- | --- | --- |
| Company | Organization; /#organization | Approved common and legal names describe the same company. |
| Website | WebSite; /#website | Homepage URL and site name belong to this website. |
| Publisher | Reference to /#organization | The website's publisher resolves to the company node. |
| Logo | /logo.svg?variant=ready | Replace the fixture URL and fetch the actual published image. |
| Emitter | One homepage JSON-LD block | Review existing output and retain a rollback version. |

- [Check publisher's expected values](https://schema.org/publisher)
- [Resolve conflicting identity facts](https://rankecho.io/resources/fix/entity-disambiguation)
- [Trace an existing field to its emitter](https://rankecho.io/resources/find/issues/schema-content-mismatch)

## What makes the logo a separate acceptance check?

Google's organization guidance requires a logo of at least 112 by 112 pixels, in a supported format, accessible for crawling and indexing. It also recommends checking its appearance on a white background. A JSON string containing an image URL does not establish any of those asset properties.

Fetch the exact referenced URL after changing the asset host, path or permissions. Inspect its final response and image bytes, then check the real dimensions and appearance. A successful homepage response is only evidence about the homepage. The copied lab makes that dependency visible by keeping the page healthy while changing the image response.

The lab serves an original SVG mark with explicit dimensions and a white canvas; SVG is a supported image format. Its checker reads those fixture attributes. It does not decode arbitrary images, inspect SVG styling, assess visual legibility or prove Google can retrieve the asset. Use an image viewer and the actual host's access checks for those production decisions.

- [Check the current logo requirements](https://developers.google.com/search/docs/appearance/structured-data/organization)
- [Review supported image formats](https://developers.google.com/search/docs/appearance/google-images)

## What did the runnable logo tests show?

We ran the copied program on September 12, 2026. It serves three homepage variants on a temporary loopback port, extracts each fixed-shape graph, follows the company's logo URL and checks the actual response. Every case retains the website-to-company publisher reference. The script asserts the expected positive and negative outcomes before printing its results.

The small case serves valid SVG with 96 by 96 dimensions. The missing case returns a plain-text 404. Both retain a 200 homepage response and parseable JSON-LD. Repair the image dependency in those cases; replacing the company name or adding more organization properties does not resolve either failure.

The ready case passes this local status, MIME and dimension check. Treat that result as a completed fixture check, with production access and appearance still outstanding. The test never contacts example.com or any public website; --html prints a separate example.com version for inspection and code validation.

| Variant | Homepage / publisher | Fetched logo | Local decision |
| --- | --- | --- | --- |
| ready | 200 / matching company ID | 200; image/svg+xml; 256 × 256 | Pass the three local asset checks. |
| small | 200 / matching company ID | 200; image/svg+xml; 96 × 96 | Replace the undersized asset. |
| missing | 200 / matching company ID | 404; text/plain; no dimensions | Restore the file or correct its URL. |


## What did the external markup validator establish?

We submitted the complete HTML printed by --html to Schema.org's public Code snippet test on September 12. It displayed one WebSite with the linked Organization expanded under publisher, zero errors and zero warnings. The two source nodes appeared as one connected result; that display did not mean the company disappeared.

This was a pasted-code observation. We did not validate a publicly deployed Cedar Quay site or use the validator to verify its fictional logo. Keep the graph result alongside the separate HTTP lab results. The public validator and the local fixed-fixture checker perform different checks, and neither certifies the real company's facts.

Google's Rich Results Test does not support site names. Use the Schema.org validator for the markup and the documented homepage requirements for that task. No Google test verdict, selected site name, knowledge panel, indexed image or improved search outcome is claimed here.

- [Read the Schema.org validator documentation](https://schema.org/docs/validator.html)
- [Test the exact HTML](https://validator.schema.org/)
- [Review site-name testing guidance](https://developers.google.com/search/docs/appearance/site-names)

## What should the production handoff contain?

Completed fictional handoff: propose one company homepage graph with the website's publisher referencing Cedar Quay. The pasted graph passed Schema.org. The 256-pixel fixture passed local asset checks; the small and missing cases correctly failed. Replace all fictional values and test URLs. Production image access, rendering and indexing remain unverified, so this is not a completed real-site launch.

For the real release, attach the approved field map, exact proposed HTML, logo URL, asset inspection, emitter diff and rollback version. Name the page and asset owners. After deployment, capture the served homepage and referenced file again, inspect crawl restrictions on both hosts, and use available Search Console inspection for Google's page view. Retain unresolved checks in the handoff.

RankEcho's Fix Engine supports the reviewed page-change workflow. Preview a sample fix when you need a scoped implementation proposal and acceptance record. This guide does not describe native logo certification or automatic deployment. Later search and referral observations belong in a separate measurement record, with no presumed schema effect.

- [Preview a reviewed page fix](https://rankecho.io/sample-fix)
- [Explore the Fix Engine](https://rankecho.io/product/fix-engine)
- [Keep later observations separate](https://rankecho.io/resources/prove/fixed-prompt-retest)

## Do Organization and SoftwareApplication describe the same thing?

No. This example describes the publishing company and its website. Use the software guide for the application and its offer; keep the entities distinct even when their brand names overlap.

## Should I copy organization markup onto every page?

Google recommends the homepage or one organization-describing page. Review the existing implementation and applicable subtype before deciding where the company record belongs.

## Does a valid logo URL mean the logo works?

No. The local example keeps parseable markup and a working homepage while the image is undersized or returns 404. Fetch and inspect the actual asset separately.

## Will this choose our site name or create a knowledge panel?

No result is guaranteed. The example establishes a graph-validation observation and local asset checks; it does not establish Google's selection, indexing or display.
